Skip to content

Commit

Permalink
Add language and direction to computed values
Browse files Browse the repository at this point in the history
  • Loading branch information
TriangulumDesire committed Jan 8, 2024
1 parent 76466a2 commit 78d2757
Show file tree
Hide file tree
Showing 14 changed files with 145 additions and 69 deletions.
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

0 comments on commit 78d2757

Please sign in to comment.