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>
37 VisualModelPtr mVisualModel;
38 LogicalModelPtr mLogicalModel;
39 TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
45 mImpl = new View::Impl();
47 mImpl->mFontClient = TextAbstraction::FontClient::Get();
55 void View::SetVisualModel(VisualModelPtr visualModel)
57 mImpl->mVisualModel = visualModel;
60 void View::SetLogicalModel(LogicalModelPtr logicalModel)
62 mImpl->mLogicalModel = logicalModel;
65 const Vector2& View::GetControlSize() const
67 if(mImpl->mVisualModel)
69 return mImpl->mVisualModel->mControlSize;
75 const Vector2& View::GetLayoutSize() const
77 if(mImpl->mVisualModel)
79 return mImpl->mVisualModel->GetLayoutSize();
85 Length View::GetNumberOfGlyphs() const
87 if(mImpl->mVisualModel)
89 const VisualModel& model = *mImpl->mVisualModel;
91 const Length glyphCount = model.mGlyphs.Count();
92 const Length positionCount = model.mGlyphPositions.Count();
94 DALI_ASSERT_DEBUG(positionCount <= glyphCount && "Invalid glyph positions in Model");
96 return (positionCount < glyphCount) ? positionCount : glyphCount;
102 Length View::GetGlyphs(GlyphInfo* glyphs,
103 Vector2* glyphPositions,
104 float& minLineOffset,
105 GlyphIndex glyphIndex,
106 Length numberOfGlyphs) const
108 Length numberOfLaidOutGlyphs = 0u;
109 Length numberOfActualLaidOutGlyphs = 0u;
110 const float characterSpacing = mImpl->mVisualModel->GetCharacterSpacing();
111 Vector<CharacterIndex>& glyphToCharacterMap = mImpl->mVisualModel->mGlyphsToCharacters;
112 const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
113 float calculatedAdvance = 0.f;
114 const Character* textBuffer = mImpl->mLogicalModel->mText.Begin();
116 if(mImpl->mVisualModel)
118 bool textElided = false;
119 DevelText::EllipsisPosition::Type ellipsisPosition = GetEllipsisPosition();
121 //Reset indices of ElidedGlyphs
122 mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(0u);
123 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(numberOfGlyphs);
124 mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(0u);
125 mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(0u);
127 // If ellipsis is enabled, the number of glyphs the layout engine has laid out may be less than 'numberOfGlyphs'.
128 // Check the last laid out line to know if the layout engine elided some text.
130 const Length numberOfLines = mImpl->mVisualModel->mLines.Count();
131 if(numberOfLines > 0u)
133 const LineRun* const lines = mImpl->mVisualModel->mLines.Begin();
135 //Get line of ellipsis
136 const LineRun* ellipsisLine = nullptr;
137 const LineRun* ellipsisNextLine = nullptr;
138 bool hasEllipsis = false;
139 for(Length lineIndex = 0; lineIndex < numberOfLines; lineIndex++)
141 const LineRun* line = (lines + lineIndex);
146 if(lineIndex < numberOfLines - 1u)
148 ellipsisNextLine = (lines + lineIndex + 1u);
154 // If ellipsis is enabled, calculate the number of laid out glyphs.
155 // Otherwise use the given number of glyphs.
159 numberOfLaidOutGlyphs = numberOfGlyphs;
161 if(ellipsisPosition == DevelText::EllipsisPosition::START)
163 numberOfActualLaidOutGlyphs = numberOfGlyphs - ellipsisLine->glyphRun.glyphIndex;
165 else if(ellipsisPosition == DevelText::EllipsisPosition::MIDDLE)
167 numberOfActualLaidOutGlyphs = 0u;
168 for(Length lineIndex = 0u; lineIndex < numberOfLines; lineIndex++)
170 numberOfActualLaidOutGlyphs += lines[lineIndex].glyphRun.numberOfGlyphs + lines[lineIndex].glyphRunSecondHalf.numberOfGlyphs;
173 else // DevelText::EllipsisPosition::END
175 numberOfActualLaidOutGlyphs = ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs;
180 numberOfActualLaidOutGlyphs = numberOfLaidOutGlyphs = numberOfGlyphs;
183 if(0u < numberOfActualLaidOutGlyphs)
185 // Retrieve from the visual model the glyphs and positions.
186 mImpl->mVisualModel->GetGlyphs(glyphs,
188 numberOfLaidOutGlyphs);
190 mImpl->mVisualModel->GetGlyphPositions(glyphPositions,
192 numberOfLaidOutGlyphs);
194 // Get the lines for the given range of glyphs.
195 // The lines contain the alignment offset which needs to be added to the glyph's position.
196 LineIndex firstLineIndex = 0u;
197 Length numberOfLines = 0u;
198 mImpl->mVisualModel->GetNumberOfLines(glyphIndex,
199 numberOfLaidOutGlyphs,
203 Vector<LineRun> lines;
204 lines.Resize(numberOfLines);
205 LineRun* lineBuffer = lines.Begin();
207 mImpl->mVisualModel->GetLinesOfGlyphRange(lineBuffer,
209 numberOfLaidOutGlyphs);
211 // Get the first line for the given glyph range.
212 LineIndex lineIndex = firstLineIndex;
213 LineRun* line = lineBuffer + lineIndex;
215 // Index of the last glyph of the line.
216 GlyphIndex lastGlyphIndexOfLine = (line->isSplitToTwoHalves ? line->glyphRunSecondHalf.glyphIndex + line->glyphRunSecondHalf.numberOfGlyphs : line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs) - 1u;
218 // Add the alignment offset to the glyph's position.
220 minLineOffset = line->alignmentOffset;
221 float penY = line->ascender;
222 for(Length index = 0u; index < numberOfLaidOutGlyphs; ++index)
224 Vector2& position = *(glyphPositions + index);
225 position.x += line->alignmentOffset;
228 if(lastGlyphIndexOfLine == index)
230 penY += -line->descender + line->lineSpacing;
232 // Get the next line.
235 if(lineIndex < numberOfLines)
237 line = lineBuffer + lineIndex;
238 minLineOffset = std::min(minLineOffset, line->alignmentOffset);
240 lastGlyphIndexOfLine = (line->isSplitToTwoHalves ? line->glyphRunSecondHalf.glyphIndex + line->glyphRunSecondHalf.numberOfGlyphs : line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs) - 1u;
242 penY += line->ascender;
247 // Set index where to set Ellipsis according to the selected position of Ellipsis.
248 // Start with this index to replace its glyph by Ellipsis, if the width is not enough, then remove more glyphs.
249 GlyphIndex startIndexOfEllipsis = 0u;
252 if(ellipsisPosition == DevelText::EllipsisPosition::START)
254 // It's the fisrt glyph in line.
255 startIndexOfEllipsis = ellipsisLine->glyphRun.glyphIndex;
257 else if(ellipsisPosition == DevelText::EllipsisPosition::MIDDLE)
259 // It's the second middle of the line in case the line split to two halves.
260 // Otherwise it's It's the last glyph in line (line before all removed lines).
261 startIndexOfEllipsis = ellipsisLine->isSplitToTwoHalves ? (ellipsisLine->glyphRunSecondHalf.glyphIndex) : (ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs - 1u);
263 else // DevelText::EllipsisPosition::END
265 // It's the last glyph in line.
266 startIndexOfEllipsis = ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs - 1u;
270 if(1u == numberOfLaidOutGlyphs)
272 // not a point try to do ellipsis with only one laid out character.
274 return numberOfLaidOutGlyphs;
279 const LineRun& elidedLine = *ellipsisLine;
281 if((1u == numberOfLines) &&
282 (GetLineHeight(elidedLine) > mImpl->mVisualModel->mControlSize.height))
284 // Replace the first glyph with ellipsis glyph
285 auto indexOfFirstGlyph = (ellipsisPosition == DevelText::EllipsisPosition::START) ? startIndexOfEllipsis : 0u;
287 // Regardless where the location of ellipsis,in-case the hight of line is greater than control's height
288 // then replace the first glyph with ellipsis glyph.
290 // Get the first glyph which is going to be replaced and the ellipsis glyph.
291 GlyphInfo& glyphInfo = *(glyphs + indexOfFirstGlyph);
292 const GlyphInfo& ellipsisGlyph = mImpl->mFontClient.GetEllipsisGlyph(mImpl->mFontClient.GetPointSize(glyphInfo.fontId));
294 // Change the 'x' and 'y' position of the ellipsis glyph.
295 Vector2& position = *(glyphPositions + indexOfFirstGlyph);
296 position.x = ellipsisGlyph.xBearing;
297 position.y = mImpl->mVisualModel->mControlSize.height - ellipsisGlyph.yBearing;
299 // Replace the glyph by the ellipsis glyph.
300 glyphInfo = ellipsisGlyph;
302 mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(indexOfFirstGlyph);
303 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(indexOfFirstGlyph);
304 mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(indexOfFirstGlyph);
305 mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(indexOfFirstGlyph);
307 numberOfLaidOutGlyphs = 1u;
309 return numberOfLaidOutGlyphs;
312 // firstPenX, penY and firstPenSet are used to position the ellipsis glyph if needed.
313 float firstPenX = 0.f; // Used if rtl text is elided.
315 bool firstPenSet = false;
317 // Add the ellipsis glyph.
318 bool inserted = false;
319 float removedGlypsWidth = 0.f;
320 Length numberOfRemovedGlyphs = 0u;
321 GlyphIndex indexOfEllipsis = startIndexOfEllipsis;
323 // Tail Mode: start by the end of line.
324 const bool isTailMode = ellipsisPosition == DevelText::EllipsisPosition::END ||
325 (ellipsisPosition == DevelText::EllipsisPosition::MIDDLE && numberOfLines != 1u);
327 // The ellipsis glyph has to fit in the place where the last glyph(s) is(are) removed.
330 const GlyphInfo& glyphToRemove = *(glyphs + indexOfEllipsis);
332 if(0u != glyphToRemove.fontId)
334 // i.e. The font id of the glyph shaped from the '\n' character is zero.
336 // Need to reshape the glyph as the font may be different in size.
337 const GlyphInfo& ellipsisGlyph = mImpl->mFontClient.GetEllipsisGlyph(mImpl->mFontClient.GetPointSize(glyphToRemove.fontId));
341 const Vector2& position = *(glyphPositions + indexOfEllipsis);
343 // Calculates the penY of the current line. It will be used to position the ellipsis glyph.
344 penY = position.y + glyphToRemove.yBearing;
346 // Calculates the first penX which will be used if rtl text is elided.
347 firstPenX = position.x - glyphToRemove.xBearing;
348 if(firstPenX < -ellipsisGlyph.xBearing)
350 // Avoids to exceed the bounding box when rtl text is elided.
351 firstPenX = -ellipsisGlyph.xBearing;
354 removedGlypsWidth = -ellipsisGlyph.xBearing;
359 calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + indexOfEllipsis))), characterSpacing, glyphToRemove.advance);
360 removedGlypsWidth += std::min(calculatedAdvance, (glyphToRemove.xBearing + glyphToRemove.width));
362 // Calculate the width of the ellipsis glyph and check if it fits.
363 const float ellipsisGlyphWidth = ellipsisGlyph.width + ellipsisGlyph.xBearing;
364 if((ellipsisGlyphWidth < removedGlypsWidth) || (isTailMode ? (indexOfEllipsis == 0u) : (indexOfEllipsis == numberOfGlyphs - 1u)))
366 GlyphInfo& glyphInfo = *(glyphs + indexOfEllipsis);
367 Vector2& position = *(glyphPositions + indexOfEllipsis);
368 position.x -= (0.f > glyphInfo.xBearing) ? glyphInfo.xBearing : 0.f;
370 // Replace the glyph by the ellipsis glyph.
371 glyphInfo = ellipsisGlyph;
373 // Change the 'x' and 'y' position of the ellipsis glyph.
375 if(position.x > firstPenX)
377 position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth;
380 position.x += ellipsisGlyph.xBearing;
381 position.y = penY - ellipsisGlyph.yBearing;
389 if(isTailMode && indexOfEllipsis > 0u)
391 // Tail Mode: remove glyphs from startIndexOfEllipsis then decrement indexOfEllipsis, until arrive to index zero.
394 else if(!isTailMode && indexOfEllipsis < numberOfLaidOutGlyphs - 1u)
396 // Not Tail Mode: remove glyphs from startIndexOfEllipsis then increase indexOfEllipsis, until arrive to last index (numberOfGlyphs - 1u).
401 // No space for the ellipsis.
404 ++numberOfRemovedGlyphs;
408 // 'Removes' all the glyphs after the ellipsis glyph.
409 if(ellipsisPosition == DevelText::EllipsisPosition::MIDDLE)
411 //Reduce size, shift glyphs and start from ellipsis glyph
412 numberOfLaidOutGlyphs = numberOfActualLaidOutGlyphs - numberOfRemovedGlyphs;
414 GlyphIndex firstMiddleIndexOfElidedGlyphs = 0u;
415 GlyphIndex secondMiddleIndexOfElidedGlyphs = 0u;
417 bool isOnlySecondHalf = false;
420 // Multi-lines case with MIDDLE
421 // In case the Ellipsis in the end of line,
422 // then this index will be the firstMiddleIndex.
423 // The secondMiddleIndex will be the fisrt index in next line.
424 // But in case there is no line after Ellipsis's line then secondMiddleIndex and endIndex equal firstMiddle
426 // A: are laid out glyphs in line has Ellipsis in the end.
427 // N: are laid out glyphs in lines after removed lines.
428 // R: are removed glyphs.
429 // L: are removed glyphs when removed lines.
430 // AAAAAAAAAAAA...RRR => Here's the firstMiddleIndex (First index after last A)
433 // NNNNNNNNNNNNNN => Here's the secondMiddleIndex (First N)
436 firstMiddleIndexOfElidedGlyphs = indexOfEllipsis;
437 if(ellipsisNextLine != nullptr)
439 secondMiddleIndexOfElidedGlyphs = ellipsisNextLine->glyphRun.glyphIndex;
443 secondMiddleIndexOfElidedGlyphs = firstMiddleIndexOfElidedGlyphs;
444 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(firstMiddleIndexOfElidedGlyphs);
449 // Single line case with MIDDLE
450 // In case the Ellipsis in the middle of line,
451 // Then the last index in first half will be firstMiddleIndex.
452 // And the indexOfEllipsis will be secondMiddleIndex, which is the first index in second half.
454 // A: are laid out glyphs in first half of line.
455 // N: are laid out glyphs in second half of line.
456 // R: are removed glyphs.
457 // L: re removed glyphs when layouting text
458 // AAAAAAALLLLLLLLLLLRRR...NNNNN
459 // firstMiddleIndex (index of last A)
460 // secondMiddleIndex (index before first N)
462 firstMiddleIndexOfElidedGlyphs = (ellipsisLine->glyphRun.numberOfGlyphs > 0u) ? (ellipsisLine->glyphRun.glyphIndex + ellipsisLine->glyphRun.numberOfGlyphs - 1u) : (ellipsisLine->glyphRun.glyphIndex);
463 secondMiddleIndexOfElidedGlyphs = indexOfEllipsis;
464 isOnlySecondHalf = ellipsisLine->glyphRun.numberOfGlyphs == 0u && ellipsisLine->glyphRunSecondHalf.numberOfGlyphs > 0u;
467 mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(firstMiddleIndexOfElidedGlyphs);
468 mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(secondMiddleIndexOfElidedGlyphs);
470 // The number of shifted glyphs and shifting positions will be different according to Single-line or Multi-lines.
471 // isOnlySecondHalf will be true when MIDDLE Ellipsis glyph in single line.
474 Length numberOfSecondHalfGlyphs = numberOfLaidOutGlyphs - firstMiddleIndexOfElidedGlyphs;
476 //Copy elided glyphs after the ellipsis glyph.
477 memcpy(glyphs + firstMiddleIndexOfElidedGlyphs, glyphs + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(GlyphInfo));
478 memcpy(glyphPositions + firstMiddleIndexOfElidedGlyphs, glyphPositions + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(Vector2));
482 Length numberOfSecondHalfGlyphs = numberOfLaidOutGlyphs - firstMiddleIndexOfElidedGlyphs + 1u;
484 //Copy elided glyphs after the ellipsis glyph.
485 memcpy(glyphs + firstMiddleIndexOfElidedGlyphs + 1u, glyphs + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(GlyphInfo));
486 memcpy(glyphPositions + firstMiddleIndexOfElidedGlyphs + 1u, glyphPositions + secondMiddleIndexOfElidedGlyphs, numberOfSecondHalfGlyphs * sizeof(Vector2));
489 else if(ellipsisPosition == DevelText::EllipsisPosition::START)
491 numberOfLaidOutGlyphs = numberOfActualLaidOutGlyphs - numberOfRemovedGlyphs;
492 //Copy elided glyphs after the ellipsis glyph.
493 memcpy(glyphs, glyphs + startIndexOfEllipsis + numberOfRemovedGlyphs, numberOfLaidOutGlyphs * sizeof(GlyphInfo));
494 memcpy(glyphPositions, glyphPositions + startIndexOfEllipsis + numberOfRemovedGlyphs, numberOfLaidOutGlyphs * sizeof(Vector2));
495 mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(indexOfEllipsis);
497 else // DevelText::EllipsisPosition::END
499 numberOfLaidOutGlyphs = numberOfActualLaidOutGlyphs - numberOfRemovedGlyphs;
500 mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(indexOfEllipsis);
507 return numberOfLaidOutGlyphs;
510 const Vector4* const View::GetColors() const
512 if(mImpl->mVisualModel)
514 return mImpl->mVisualModel->mColors.Begin();
520 const ColorIndex* const View::GetColorIndices() const
522 if(mImpl->mVisualModel)
524 return mImpl->mVisualModel->mColorIndices.Begin();
530 const Vector4* const View::GetBackgroundColors() const
532 if(mImpl->mVisualModel)
534 return mImpl->mVisualModel->mBackgroundColors.Begin();
540 const ColorIndex* const View::GetBackgroundColorIndices() const
542 if(mImpl->mVisualModel)
544 return mImpl->mVisualModel->mBackgroundColorIndices.Begin();
550 bool const View::IsMarkupBackgroundColorSet() const
552 if(mImpl->mVisualModel)
554 return (mImpl->mVisualModel->mBackgroundColors.Count() > 0);
560 const Vector4& View::GetTextColor() const
562 if(mImpl->mVisualModel)
564 return mImpl->mVisualModel->GetTextColor();
566 return Vector4::ZERO;
569 const Vector2& View::GetShadowOffset() const
571 if(mImpl->mVisualModel)
573 return mImpl->mVisualModel->GetShadowOffset();
575 return Vector2::ZERO;
578 const Vector4& View::GetShadowColor() const
580 if(mImpl->mVisualModel)
582 return mImpl->mVisualModel->GetShadowColor();
584 return Vector4::ZERO;
587 const Vector4& View::GetUnderlineColor() const
589 if(mImpl->mVisualModel)
591 return mImpl->mVisualModel->GetUnderlineColor();
593 return Vector4::ZERO;
596 bool View::IsUnderlineEnabled() const
598 if(mImpl->mVisualModel)
600 return mImpl->mVisualModel->IsUnderlineEnabled();
605 const GlyphInfo* View::GetHyphens() const
607 if(mImpl->mVisualModel)
609 return mImpl->mVisualModel->mHyphen.glyph.Begin();
615 const Length* View::GetHyphenIndices() const
617 if(mImpl->mVisualModel)
619 return mImpl->mVisualModel->mHyphen.index.Begin();
625 Length View::GetHyphensCount() const
627 if(mImpl->mVisualModel)
629 return mImpl->mVisualModel->mHyphen.glyph.Size();
634 float View::GetUnderlineHeight() const
636 if(mImpl->mVisualModel)
638 return mImpl->mVisualModel->GetUnderlineHeight();
643 Text::Underline::Type View::GetUnderlineType() const
645 Text::Underline::Type type = Text::Underline::Type::SOLID;
646 if(mImpl->mVisualModel)
648 type = mImpl->mVisualModel->GetUnderlineType();
653 float View::GetDashedUnderlineWidth() const
656 if(mImpl->mVisualModel)
658 width = mImpl->mVisualModel->GetDashedUnderlineWidth();
663 float View::GetDashedUnderlineGap() const
666 if(mImpl->mVisualModel)
668 gap = mImpl->mVisualModel->GetDashedUnderlineGap();
673 Length View::GetNumberOfUnderlineRuns() const
675 if(mImpl->mVisualModel)
677 return mImpl->mVisualModel->GetNumberOfUnderlineRuns();
683 void View::GetUnderlineRuns(GlyphRun* underlineRuns,
684 UnderlineRunIndex index,
685 Length numberOfRuns) const
687 if(mImpl->mVisualModel)
689 mImpl->mVisualModel->GetUnderlineRuns(underlineRuns,
695 const Vector4& View::GetOutlineColor() const
697 if(mImpl->mVisualModel)
699 return mImpl->mVisualModel->GetOutlineColor();
701 return Vector4::ZERO;
704 uint16_t View::GetOutlineWidth() const
706 if(mImpl->mVisualModel)
708 return mImpl->mVisualModel->GetOutlineWidth();
713 DevelText::EllipsisPosition::Type View::GetEllipsisPosition() const
715 DevelText::EllipsisPosition::Type ellipsisPosition = DevelText::EllipsisPosition::END;
716 if(mImpl->mVisualModel)
718 const VisualModel& model = *mImpl->mVisualModel;
719 ellipsisPosition = model.GetEllipsisPosition();
722 return ellipsisPosition;
725 bool View::IsTextElideEnabled() const
727 bool isTextElideEnabled = false;
729 if(mImpl->mVisualModel)
731 const VisualModel& model = *mImpl->mVisualModel;
732 isTextElideEnabled = model.IsTextElideEnabled();
735 return isTextElideEnabled;
738 GlyphIndex View::GetStartIndexOfElidedGlyphs() const
740 GlyphIndex startIndexOfElidedGlyphs = 0u;
742 if(mImpl->mVisualModel)
744 const VisualModel& model = *mImpl->mVisualModel;
745 startIndexOfElidedGlyphs = model.GetStartIndexOfElidedGlyphs();
748 return startIndexOfElidedGlyphs;
751 GlyphIndex View::GetEndIndexOfElidedGlyphs() const
753 GlyphIndex endIndexOfElidedGlyphs = 0u;
755 if(mImpl->mVisualModel)
757 const VisualModel& model = *mImpl->mVisualModel;
758 endIndexOfElidedGlyphs = model.GetEndIndexOfElidedGlyphs();
761 return endIndexOfElidedGlyphs;
764 GlyphIndex View::GetFirstMiddleIndexOfElidedGlyphs() const
766 GlyphIndex firstMiddleIndexOfElidedGlyphs = 0u;
768 if(mImpl->mVisualModel)
770 const VisualModel& model = *mImpl->mVisualModel;
771 firstMiddleIndexOfElidedGlyphs = model.GetFirstMiddleIndexOfElidedGlyphs();
774 return firstMiddleIndexOfElidedGlyphs;
777 GlyphIndex View::GetSecondMiddleIndexOfElidedGlyphs() const
779 GlyphIndex secondMiddleIndexOfElidedGlyphs = 0u;
781 if(mImpl->mVisualModel)
783 const VisualModel& model = *mImpl->mVisualModel;
784 secondMiddleIndexOfElidedGlyphs = model.GetSecondMiddleIndexOfElidedGlyphs();
787 return secondMiddleIndexOfElidedGlyphs;
790 const Vector4& View::GetStrikethroughColor() const
792 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughColor() : Vector4::ZERO;
795 bool View::IsStrikethroughEnabled() const
797 return (mImpl->mVisualModel) ? mImpl->mVisualModel->IsStrikethroughEnabled() : false;
800 float View::GetStrikethroughHeight() const
802 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughHeight() : 0.0f;
805 Length View::GetNumberOfStrikethroughRuns() const
807 if(mImpl->mVisualModel)
809 return mImpl->mVisualModel->GetNumberOfStrikethroughRuns();
815 void View::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns,
816 StrikethroughRunIndex index,
817 Length numberOfRuns) const
819 if(mImpl->mVisualModel)
821 mImpl->mVisualModel->GetStrikethroughRuns(strikethroughRuns,
827 const float View::GetCharacterSpacing() const
829 return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetCharacterSpacing() : 0.f;
832 const Character* View::GetTextBuffer() const
834 return (mImpl->mVisualModel) ? mImpl->mLogicalModel->mText.Begin() : nullptr;
837 const Vector<CharacterIndex>& View::GetGlyphsToCharacters() const
839 return mImpl->mVisualModel->GetGlyphsToCharacters();
844 } // namespace Toolkit