mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
Add line-height and text-indent support.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
@@ -155,6 +155,19 @@ class EE_API RichText : public Drawable {
|
||||
/** @return The list of rendered lines. */
|
||||
const std::vector<RenderParagraph>& getLines() const { return mLines; }
|
||||
|
||||
/** Sets line-height as a multiplier of the font's default line spacing.
|
||||
* Use 0 to reset to font default. */
|
||||
void setLineHeight( Float height );
|
||||
|
||||
/** @return The line height multiplier. */
|
||||
Float getLineHeight() const { return mLineHeight; }
|
||||
|
||||
/** Sets text-indent (pixels) for the first line. */
|
||||
void setTextIndent( Float indent );
|
||||
|
||||
/** @return The text indent in pixels. */
|
||||
Float getTextIndent() const { return mTextIndent; }
|
||||
|
||||
/** @brief Sets the text selection range. */
|
||||
void setSelection( TextSelectionRange range );
|
||||
|
||||
@@ -207,6 +220,8 @@ class EE_API RichText : public Drawable {
|
||||
Sizef mSize;
|
||||
Int64 mTotalCharacterCount{ 0 };
|
||||
bool mNeedsLayoutUpdate{ true };
|
||||
Float mLineHeight{ 0 };
|
||||
Float mTextIndent{ 0 };
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
@@ -220,6 +220,8 @@ enum class PropertyId : Uint32 {
|
||||
TextAsFallback = String::hash( "text-as-fallback" ),
|
||||
SelectOnClick = String::hash( "select-on-click" ),
|
||||
LineSpacing = String::hash( "line-spacing" ),
|
||||
LineHeight = String::hash( "line-height" ),
|
||||
TextIndent = String::hash( "text-indent" ),
|
||||
GravityOwner = String::hash( "gravity-owner" ),
|
||||
Href = String::hash( "href" ),
|
||||
Focusable = String::hash( "focusable" ),
|
||||
|
||||
@@ -113,6 +113,14 @@ class EE_API UIRichText : public UIHTMLWidget {
|
||||
|
||||
UIRichText* setTextAlign( const Uint32& align );
|
||||
|
||||
Float getLineHeightPx() const { return mLineHeightPx; }
|
||||
|
||||
UIRichText* setLineHeightPx( Float height );
|
||||
|
||||
Float getTextIndentPx() const { return mTextIndentPx; }
|
||||
|
||||
UIRichText* setTextIndentPx( Float indent );
|
||||
|
||||
bool isTextSelectionEnabled() const;
|
||||
|
||||
void setTextSelectionEnabled( bool active );
|
||||
@@ -138,6 +146,8 @@ class EE_API UIRichText : public UIHTMLWidget {
|
||||
Int64 mSelCurInit{ 0 };
|
||||
Int64 mSelCurEnd{ 0 };
|
||||
bool mSelecting{ false };
|
||||
Float mLineHeightPx{ 0 };
|
||||
Float mTextIndentPx{ 0 };
|
||||
|
||||
explicit UIRichText( const std::string& tag = "richtext" );
|
||||
|
||||
|
||||
@@ -130,6 +130,20 @@ void RichText::setSelection( TextSelectionRange range ) {
|
||||
}
|
||||
}
|
||||
|
||||
void RichText::setLineHeight( Float height ) {
|
||||
if ( mLineHeight != height ) {
|
||||
mLineHeight = height;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void RichText::setTextIndent( Float indent ) {
|
||||
if ( mTextIndent != indent ) {
|
||||
mTextIndent = indent;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void RichText::setSelectionColor( const Color& color ) {
|
||||
mSelectionColor = color;
|
||||
}
|
||||
@@ -466,7 +480,7 @@ void RichText::updateLayout() {
|
||||
mLines.clear();
|
||||
mLines.push_back( RenderParagraph() );
|
||||
|
||||
Float curX = 0;
|
||||
Float curX = mTextIndent;
|
||||
Float maxWidth = 0;
|
||||
Int64 curCharIdx = 0;
|
||||
|
||||
@@ -524,7 +538,9 @@ void RichText::updateLayout() {
|
||||
renderSpanText->setStyleConfig( fontStyle );
|
||||
|
||||
Float ascent = fontStyle.Font->getAscent( fontStyle.CharacterSize );
|
||||
Float height = fontStyle.Font->getLineSpacing( fontStyle.CharacterSize );
|
||||
Float height = mLineHeight > 0
|
||||
? mLineHeight
|
||||
: fontStyle.Font->getLineSpacing( fontStyle.CharacterSize );
|
||||
Float spanWidth = renderSpanText->getTextWidth();
|
||||
|
||||
RenderSpan renderSpan;
|
||||
@@ -686,7 +702,7 @@ void RichText::updateLayout() {
|
||||
mLines.clear();
|
||||
mLines.push_back( RenderParagraph() );
|
||||
|
||||
Float curX = 0;
|
||||
Float curX = mTextIndent;
|
||||
Float maxWidth = 0;
|
||||
Int64 curCharIdx = 0;
|
||||
|
||||
@@ -805,7 +821,9 @@ void RichText::updateLayout() {
|
||||
renderSpanText->setStyleConfig( fontStyle );
|
||||
|
||||
Float ascent = fontStyle.Font->getAscent( fontStyle.CharacterSize );
|
||||
Float height = fontStyle.Font->getLineSpacing( fontStyle.CharacterSize );
|
||||
Float height = mLineHeight > 0
|
||||
? mLineHeight
|
||||
: fontStyle.Font->getLineSpacing( fontStyle.CharacterSize );
|
||||
Float spanWidth = renderSpanText->getTextWidth();
|
||||
|
||||
RenderSpan renderSpan;
|
||||
|
||||
@@ -229,6 +229,8 @@ void StyleSheetSpecification::registerDefaultProperties() {
|
||||
registerProperty( "font-style", "", true ).addAlias( "font-weight" );
|
||||
registerProperty( "text-decoration", "", true );
|
||||
registerProperty( "line-spacing", "", true ).setType( PropertyType::NumberLength );
|
||||
registerProperty( "line-height", "", true ).setType( PropertyType::NumberLength );
|
||||
registerProperty( "text-indent", "", true ).setType( PropertyType::NumberLength );
|
||||
registerProperty( "text-stroke-width", "", true )
|
||||
.setType( PropertyType::NumberLength )
|
||||
.addAlias( "fontoutlinethickness" );
|
||||
|
||||
@@ -316,6 +316,33 @@ bool UIRichText::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
mDataProperties["data-language"] = attribute;
|
||||
break;
|
||||
}
|
||||
case PropertyId::LineHeight: {
|
||||
std::string val = attribute.value();
|
||||
if ( val == "normal" || val.empty() ) {
|
||||
setLineHeightPx( 0 );
|
||||
} else {
|
||||
// Unitless number: multiplier of font size
|
||||
bool isUnitless = !val.empty();
|
||||
for ( char c : val ) {
|
||||
if ( c != '-' && c != '+' && c != '.' && !String::isNumber( c, false ) ) {
|
||||
isUnitless = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isUnitless ) {
|
||||
Float multiplier = StyleSheetLength::fromString( val, 0 ).getValue();
|
||||
setLineHeightPx( multiplier * getFontSize() );
|
||||
} else {
|
||||
setLineHeightPx( lengthFromValue( attribute ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PropertyId::TextIndent: {
|
||||
setTextIndentPx( lengthFromValue( attribute ) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return UIHTMLWidget::applyProperty( attribute );
|
||||
}
|
||||
@@ -360,6 +387,10 @@ std::string UIRichText::getPropertyString( const PropertyDefinition* propertyDef
|
||||
return getTextAlign() == TEXT_ALIGN_CENTER
|
||||
? "center"
|
||||
: ( getTextAlign() == TEXT_ALIGN_RIGHT ? "right" : "left" );
|
||||
case PropertyId::LineHeight:
|
||||
return mLineHeightPx > 0 ? String::fromFloat( mLineHeightPx, "px" ) : "normal";
|
||||
case PropertyId::TextIndent:
|
||||
return mTextIndentPx > 0 ? String::fromFloat( mTextIndentPx, "px" ) : "0";
|
||||
default:
|
||||
return UIHTMLWidget::getPropertyString( propertyDef, propertyIndex );
|
||||
}
|
||||
@@ -372,7 +403,7 @@ std::vector<PropertyId> UIRichText::getPropertiesImplemented() const {
|
||||
PropertyId::Color, PropertyId::TextShadowColor, PropertyId::TextShadowOffset,
|
||||
PropertyId::TextStrokeWidth, PropertyId::TextStrokeColor, PropertyId::TextAlign,
|
||||
PropertyId::SelectionColor, PropertyId::SelectionBackColor, PropertyId::TextSelection,
|
||||
PropertyId::TextDecoration };
|
||||
PropertyId::TextDecoration, PropertyId::LineHeight, PropertyId::TextIndent };
|
||||
props.insert( props.end(), local.begin(), local.end() );
|
||||
return props;
|
||||
}
|
||||
@@ -542,6 +573,24 @@ UIRichText* UIRichText::setTextAlign( const Uint32& align ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
UIRichText* UIRichText::setLineHeightPx( Float height ) {
|
||||
if ( mLineHeightPx != height ) {
|
||||
mLineHeightPx = height;
|
||||
notifyLayoutAttrChange();
|
||||
notifyLayoutAttrChangeParent();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
UIRichText* UIRichText::setTextIndentPx( Float indent ) {
|
||||
if ( mTextIndentPx != indent ) {
|
||||
mTextIndentPx = indent;
|
||||
notifyLayoutAttrChange();
|
||||
notifyLayoutAttrChangeParent();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void UIRichText::loadFromXmlNode( const pugi::xml_node& node ) {
|
||||
beginAttributesTransaction();
|
||||
|
||||
@@ -657,6 +706,11 @@ String UIRichText::UIRichText::collapseInternalWhitespace( const String& s ) {
|
||||
|
||||
void UIRichText::rebuildRichText( UILayout* container, RichText& richText, IntrinsicMode mode ) {
|
||||
richText.clear();
|
||||
if ( container->isType( UI_TYPE_RICHTEXT ) ) {
|
||||
auto* uiRt = static_cast<UIRichText*>( container );
|
||||
richText.setLineHeight( uiRt->getLineHeightPx() );
|
||||
richText.setTextIndent( uiRt->getTextIndentPx() );
|
||||
}
|
||||
Float maxWidth = 0;
|
||||
if ( container->getLayoutWidthPolicy() == SizePolicy::WrapContent ) {
|
||||
maxWidth = container->getMatchParentWidth() - container->getPixelsContentOffset().Left -
|
||||
|
||||
@@ -20,6 +20,8 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
richText.getFontStyleConfig().Font = font;
|
||||
richText.getFontStyleConfig().CharacterSize = 24;
|
||||
richText.setAlign( TEXT_ALIGN_LEFT );
|
||||
richText.setLineHeight( 36 ); // Line height of 36px (1.5x 24px font)
|
||||
richText.setTextIndent( 30 ); // Indent first line 30px
|
||||
|
||||
// Add spans using the helper method
|
||||
richText.addSpan( "Hello " );
|
||||
|
||||
Reference in New Issue
Block a user