Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attributes and properties for language and direction #563

Merged
merged 3 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMake/FileList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ set(Core_PUB_HDR_FILES
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleTypes.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/SystemInterface.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Texture.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TextShapingContext.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Traits.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Transform.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TransformPrimitive.h
Expand Down
1 change: 1 addition & 0 deletions Include/RmlUi/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#include "Core/StyleSheetSpecification.h"
#include "Core/StyleTypes.h"
#include "Core/SystemInterface.h"
#include "Core/TextShapingContext.h"
#include "Core/Texture.h"
#include "Core/Transform.h"
#include "Core/TransformPrimitive.h"
Expand Down
10 changes: 9 additions & 1 deletion Include/RmlUi/Core/ComputedValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ namespace Style {
font_weight(FontWeight::Normal), has_letter_spacing(0), font_style(FontStyle::Normal), has_font_effect(false),
pointer_events(PointerEvents::Auto), focus(Focus::Auto), text_align(TextAlign::Left), text_decoration(TextDecoration::None),
text_transform(TextTransform::None), white_space(WhiteSpace::Normal), word_break(WordBreak::Normal),
line_height_inherit_type(LineHeight::Number)
direction(Direction::Auto), line_height_inherit_type(LineHeight::Number)
{}

// Font face used to render text and resolve ex properties. Does not represent a true property
Expand All @@ -141,9 +141,13 @@ namespace Style {
WhiteSpace white_space : 3;
WordBreak word_break : 2;

Direction direction : 2;

LineHeight::InheritType line_height_inherit_type : 1;
float line_height = 12.f * 1.2f;
float line_height_inherit = 1.2f;

String language = "";
};

struct RareValues {
Expand Down Expand Up @@ -257,6 +261,8 @@ namespace Style {
Colourb color() const { return inherited.color; }
float opacity() const { return inherited.opacity; }
LineHeight line_height() const { return LineHeight(inherited.line_height, inherited.line_height_inherit_type, inherited.line_height_inherit); }
const String& language() const { return inherited.language; }
Direction direction() const { return inherited.direction; }

// -- Rare --
MinWidth min_width() const { return LengthPercentage(rare.min_width_type, rare.min_width); }
Expand Down Expand Up @@ -349,6 +355,8 @@ namespace Style {
void color (Colourb value) { inherited.color = value; }
void opacity (float value) { inherited.opacity = value; }
void line_height (LineHeight value) { inherited.line_height = value.value; inherited.line_height_inherit_type = value.inherit_type; inherited.line_height_inherit = value.inherit_value; }
void language (const String& value) { inherited.language = value; }
void direction (Direction value) { inherited.direction = value; }
// Rare
void min_width (MinWidth value) { rare.min_width_type = value.type; rare.min_width = value.value; }
void max_width (MaxWidth value) { rare.max_width_type = value.type; rare.max_width = value.value; }
Expand Down
10 changes: 1 addition & 9 deletions Include/RmlUi/Core/FontEngineInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "Geometry.h"
#include "Header.h"
#include "StyleTypes.h"
#include "TextShapingContext.h"
#include "Types.h"

namespace Rml {
Expand All @@ -45,15 +46,6 @@ namespace Rml {

class RMLUICORE_API FontEngineInterface {
public:
/*
Data extracted from the properties of the text's element to help provide context for text shaping and spacing.
*/
struct TextShapingContext {
const Rml::String& language;
Rml::Style::Direction text_direction = Rml::Style::Direction::Auto;
float letter_spacing = 0.0f;
};

FontEngineInterface();
virtual ~FontEngineInterface();

Expand Down
4 changes: 2 additions & 2 deletions Include/RmlUi/Core/ID.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ enum class PropertyId : uint8_t {
NavDown,
NavLeft,

Language,
Direction,
RmlUi_Language,
RmlUi_Direction,

NumDefinedIds,
FirstCustomId = NumDefinedIds,
Expand Down
47 changes: 47 additions & 0 deletions Include/RmlUi/Core/TextShapingContext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* This source file is part of RmlUi, the HTML/CSS Interface Middleware
*
* For the latest information, see http://github.com/mikke89/RmlUi
*
* Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
* Copyright (c) 2019-2023 The RmlUi Team, and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

#ifndef RMLUI_CORE_TEXTSHAPINGCONTEXT_H
#define RMLUI_CORE_TEXTSHAPINGCONTEXT_H

#include "StyleTypes.h"
#include "Types.h"

namespace Rml {

/*
Data extracted from the properties of an element to help provide context for text shaping and spacing.
*/
struct TextShapingContext {
const String& language;
Style::Direction text_direction = Style::Direction::Auto;
float letter_spacing = 0.0f; // Measured in pixels.
};

} // namespace Rml
#endif
1 change: 1 addition & 0 deletions Samples/basic/bitmapfont/src/FontEngineInterfaceBitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ using Rml::Style::FontWeight;
using Rml::FontEffectList;
using Rml::FontMetrics;
using Rml::GeometryList;
using Rml::TextShapingContext;

class FontEngineInterfaceBitmap : public Rml::FontEngineInterface {
public:
Expand Down
8 changes: 4 additions & 4 deletions Source/Core/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,7 @@ void Element::OnAttributeChange(const ElementAttributes& changed_attributes)
else if (attribute == "lang")
{
if (value.GetType() == Variant::STRING)
meta->style.SetProperty(PropertyId::Language, Property(value.GetReference<String>(), Unit::STRING));
meta->style.SetProperty(PropertyId::RmlUi_Language, Property(value.GetReference<String>(), Unit::STRING));
else if (value.GetType() != Variant::NONE)
Log::Message(Log::LT_WARNING, "Invalid 'lang' attribute, string type required. In element: %s", GetAddress().c_str());
}
Expand All @@ -1659,11 +1659,11 @@ void Element::OnAttributeChange(const ElementAttributes& changed_attributes)
const String& dir_value = value.GetReference<String>();

if (dir_value == "auto")
meta->style.SetProperty(PropertyId::Direction, Property(Style::Direction::Auto));
meta->style.SetProperty(PropertyId::RmlUi_Direction, Property(Style::Direction::Auto));
else if (dir_value == "ltr")
meta->style.SetProperty(PropertyId::Direction, Property(Style::Direction::Ltr));
meta->style.SetProperty(PropertyId::RmlUi_Direction, Property(Style::Direction::Ltr));
else if (dir_value == "rtl")
meta->style.SetProperty(PropertyId::Direction, Property(Style::Direction::Rtl));
meta->style.SetProperty(PropertyId::RmlUi_Direction, Property(Style::Direction::Rtl));
else
Log::Message(Log::LT_WARNING, "Invalid 'dir' attribute '%s', value must be 'auto', 'ltr', or 'rtl'. In element: %s",
dir_value.c_str(), GetAddress().c_str());
Expand Down
10 changes: 7 additions & 3 deletions Source/Core/ElementStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,13 @@ PropertyIdSet ElementStyle::ComputeValues(Style::ComputedValues& values, const S
values.flex_basis(ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, vp_dimensions));
break;

case PropertyId::RmlUi_Language:
values.language(p->value.GetReference<String>());
break;
case PropertyId::RmlUi_Direction:
values.direction(p->Get<Direction>());
break;

// Fetched from element's properties.
case PropertyId::Cursor:
case PropertyId::Transition:
Expand All @@ -875,9 +882,6 @@ PropertyIdSet ElementStyle::ComputeValues(Style::ComputedValues& values, const S
case PropertyId::NavLeft:
case PropertyId::NavRight:
break;
// Internationalization properties (internal). Must be manually retrieved with 'GetProperty()'.
case PropertyId::Language:
case PropertyId::Direction:
// Unhandled properties. Must be manually retrieved with 'GetProperty()'.
case PropertyId::FillImage:
case PropertyId::CaretColor:
Expand Down
27 changes: 12 additions & 15 deletions Source/Core/ElementText.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "../../Include/RmlUi/Core/GeometryUtilities.h"
#include "../../Include/RmlUi/Core/Profiling.h"
#include "../../Include/RmlUi/Core/Property.h"
#include "../../Include/RmlUi/Core/TextShapingContext.h"
#include "ComputeProperty.h"
#include "ElementDefinition.h"
#include "ElementStyle.h"
Expand Down Expand Up @@ -205,10 +206,8 @@ bool ElementText::GenerateLine(String& line, int& line_length, float& line_width
bool break_at_endline =
white_space_property == WhiteSpace::Pre || white_space_property == WhiteSpace::Prewrap || white_space_property == WhiteSpace::Preline;

const FontEngineInterface::TextShapingContext text_shaping_context{
GetProperty(PropertyId::Language)->value.GetReference<String>(),
GetProperty(PropertyId::Direction)->Get<Style::Direction>(),
computed.letter_spacing()
const TextShapingContext text_shaping_context{
computed.language(), computed.direction(), computed.letter_spacing()
};

TextTransform text_transform_property = computed.text_transform();
Expand Down Expand Up @@ -357,13 +356,13 @@ void ElementText::OnPropertyChange(const PropertyIdSet& changed_properties)
}
}

if (changed_properties.Contains(PropertyId::FontFamily) || //
changed_properties.Contains(PropertyId::FontWeight) || //
changed_properties.Contains(PropertyId::FontStyle) || //
changed_properties.Contains(PropertyId::FontSize) || //
changed_properties.Contains(PropertyId::LetterSpacing) || //
changed_properties.Contains(PropertyId::Language) || //
changed_properties.Contains(PropertyId::Direction))
if (changed_properties.Contains(PropertyId::FontFamily) || //
changed_properties.Contains(PropertyId::FontWeight) || //
changed_properties.Contains(PropertyId::FontStyle) || //
changed_properties.Contains(PropertyId::FontSize) || //
changed_properties.Contains(PropertyId::LetterSpacing) || //
changed_properties.Contains(PropertyId::RmlUi_Language) || //
changed_properties.Contains(PropertyId::RmlUi_Direction))
{
font_face_changed = true;

Expand Down Expand Up @@ -466,10 +465,8 @@ void ElementText::GenerateGeometry(const FontFaceHandle font_face_handle)

void ElementText::GenerateGeometry(const FontFaceHandle font_face_handle, Line& line)
{
const FontEngineInterface::TextShapingContext text_shaping_context{
GetProperty(PropertyId::Language)->value.GetReference<String>(),
GetProperty(PropertyId::Direction)->Get<Style::Direction>(),
GetComputedValues().letter_spacing()
const TextShapingContext text_shaping_context{
GetComputedValues().language(), GetComputedValues().direction(), GetComputedValues().letter_spacing()
};

line.width = GetFontEngineInterface()->GenerateString(font_face_handle, font_effects_handle, line.text, line.position, colour, opacity,
Expand Down
7 changes: 4 additions & 3 deletions Source/Core/ElementUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "../../Include/RmlUi/Core/Factory.h"
#include "../../Include/RmlUi/Core/FontEngineInterface.h"
#include "../../Include/RmlUi/Core/RenderInterface.h"
#include "../../Include/RmlUi/Core/TextShapingContext.h"
#include "DataController.h"
#include "DataModel.h"
#include "DataView.h"
Expand Down Expand Up @@ -155,9 +156,9 @@ float ElementUtilities::GetDensityIndependentPixelRatio(Element* element)

int ElementUtilities::GetStringWidth(Element* element, const String& string, Character prior_character)
{
const FontEngineInterface::TextShapingContext text_shaping_context{
element->GetProperty(PropertyId::Language)->value.GetReference<String>(),
element->GetProperty(PropertyId::Direction)->Get<Style::Direction>(),
const TextShapingContext text_shaping_context{
element->GetComputedValues().language(),
element->GetComputedValues().direction(),
element->GetComputedValues().letter_spacing()
};

Expand Down
19 changes: 1 addition & 18 deletions Source/Core/PropertyDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include "../../Include/RmlUi/Core/PropertyDefinition.h"
#include "../../Include/RmlUi/Core/Log.h"
#include "../../Include/RmlUi/Core/StyleSheetSpecification.h"
#include "../../Include/RmlUi/Core/StyleTypes.h"

namespace Rml {

Expand Down Expand Up @@ -138,25 +137,9 @@ bool PropertyDefinition::GetValue(String& value, const Property& property) const
break;
}
}

// If we couldn't find it, exit now
if (parser_index < 0 || parser_index >= (int)parsers.size())
{
// Manually handle internal direction property
if (id == PropertyId::Direction)
{
switch (property.value.Get<Style::Direction>())
{
case Style::Direction::Auto: value = "auto"; break;
case Style::Direction::Ltr: value = "ltr"; break;
case Style::Direction::Rtl: value = "rtl"; break;
}

break;
}

// We couldn't find it, exit now
return false;
}
}

int keyword = property.value.Get<int>();
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/StyleSheetSpecification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ void StyleSheetSpecification::RegisterDefaultProperties()
RegisterShorthand(ShorthandId::FlexFlow, "flex-flow", "flex-direction, flex-wrap", ShorthandType::FallThrough);

// Internationalization properties (internal)
RegisterProperty(PropertyId::Language, "language", "", true, false);
RegisterProperty(PropertyId::Direction, "direction", "auto", true, false);
RegisterProperty(PropertyId::RmlUi_Language, "--rmlui-language", "", true, true).AddParser("string");
RegisterProperty(PropertyId::RmlUi_Direction, "--rmlui-direction", "auto", true, true).AddParser("keyword", "auto, ltr, rtl");

RMLUI_ASSERTMSG(instance->properties.shorthand_map->AssertAllInserted(ShorthandId::NumDefinedIds), "Missing specification for one or more Shorthand IDs.");
RMLUI_ASSERTMSG(instance->properties.property_map->AssertAllInserted(PropertyId::NumDefinedIds), "Missing specification for one or more Property IDs.");
Expand Down
Loading