Skip to content

Commit

Permalink
Add baseline-shift support #202
Browse files Browse the repository at this point in the history
  • Loading branch information
sammycage committed Dec 13, 2024
1 parent c7889a0 commit ba15dbc
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 3 deletions.
2 changes: 1 addition & 1 deletion source/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ class PathIterator {

private:
const plutovg_path_element_t* m_elements;
int m_size;
const int m_size;
int m_index;
};

Expand Down
14 changes: 14 additions & 0 deletions source/svglayoutstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ static Length parseLength(const std::string_view& input, LengthNegativeMode mode
return value;
}

static BaselineShift parseBaselineShift(const std::string_view& input)
{
if(input.compare("baseline") == 0)
return BaselineShift::Type::Baseline;
if(input.compare("sub") == 0)
return BaselineShift::Type::Sub;
if(input.compare("super") == 0)
return BaselineShift::Type::Super;
return parseLength(input, LengthNegativeMode::Allow, Length(0.f, LengthUnits::None));
}

static LengthList parseDashArray(std::string_view input)
{
if(input.compare("none") == 0)
Expand Down Expand Up @@ -364,6 +375,9 @@ SVGLayoutState::SVGLayoutState(const SVGLayoutState& parent, const SVGElement* e
case PropertyID::Font_Size:
m_font_size = parseFontSize(input, this);
break;
case PropertyID::Baseline_Shift:
m_baseline_shit = parseBaselineShift(input);
break;
case PropertyID::Stroke_Width:
m_stroke_width = parseLength(input, LengthNegativeMode::Forbid, Length(1.f, LengthUnits::None));
break;
Expand Down
2 changes: 2 additions & 0 deletions source/svglayoutstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class SVGLayoutState {
float stroke_miterlimit() const { return m_stroke_miterlimit; }
float font_size() const { return m_font_size; }

const BaselineShift& baseline_shit() const { return m_baseline_shit; }
const Length& stroke_width() const { return m_stroke_width; }
const Length& stroke_dashoffset() const { return m_stroke_dashoffset; }
const LengthList& stroke_dasharray() const { return m_stroke_dasharray; }
Expand Down Expand Up @@ -74,6 +75,7 @@ class SVGLayoutState {
float m_stroke_miterlimit = 4.f;
float m_font_size = 12.f;

BaselineShift m_baseline_shit;
Length m_stroke_width{1.f, LengthUnits::None};
Length m_stroke_dashoffset{0.f, LengthUnits::None};
LengthList m_stroke_dasharray;
Expand Down
3 changes: 2 additions & 1 deletion source/svgproperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ PropertyID csspropertyid(const std::string_view& name)
std::string_view name;
PropertyID value;
} table[] = {
{"baseline-shift", PropertyID::Baseline_Shift},
{"clip-path", PropertyID::Clip_Path},
{"clip-rule", PropertyID::Clip_Rule},
{"color", PropertyID::Color},
Expand Down Expand Up @@ -240,8 +241,8 @@ bool Length::parse(std::string_view input, LengthNegativeMode mode)
m_value = value * dpi / 72.f;
else
return false;
input.remove_prefix(1);
m_units = LengthUnits::Px;
input.remove_prefix(1);
break;
case 'i':
input.remove_prefix(1);
Expand Down
22 changes: 22 additions & 0 deletions source/svgproperty.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace lunasvg {

enum class PropertyID : uint8_t {
Unknown = 0,
Baseline_Shift,
Class,
ClipPathUnits,
Clip_Path,
Expand Down Expand Up @@ -327,6 +328,27 @@ class SVGLengthList final : public SVGProperty {
LengthList m_values;
};

class BaselineShift {
public:
enum class Type {
Baseline,
Sub,
Super,
Length
};

BaselineShift() = default;
BaselineShift(Type type) : m_type(type) {}
BaselineShift(const Length& length) : m_type(Type::Length), m_length(length) {}

Type type() const { return m_type; }
const Length& length() const { return m_length; }

private:
Type m_type{Type::Baseline};
Length m_length;
};

class SVGNumber : public SVGProperty {
public:
SVGNumber(PropertyID id, float value)
Expand Down
22 changes: 21 additions & 1 deletion source/svgtextelement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,26 @@ namespace lunasvg {

static float calculateBaselineOffset(const SVGTextPositioningElement* element)
{
return 0.f;
const auto& baselineShift = element->baseline_shit();
if(baselineShift.type() == BaselineShift::Type::Baseline) {
return 0.f;
}

const auto& font = element->font();
if(baselineShift.type() == BaselineShift::Type::Sub)
return -font.height() / 2.f;
if(baselineShift.type() == BaselineShift::Type::Super) {
return font.height() / 2.f;
}

const auto& length = baselineShift.length();
if(length.units() == LengthUnits::Percent)
return length.value() * font.size() / 100.f;
if(length.units() == LengthUnits::Ex)
return length.value() * font.size() / 2.f;
if(length.units() == LengthUnits::Em)
return length.value() * font.size();
return length.value();
}

static bool needsTextAnchorAdjustment(const SVGTextPositioningElement* element)
Expand Down Expand Up @@ -281,6 +300,7 @@ void SVGTextPositioningElement::layoutElement(const SVGLayoutState& state)
m_font = state.font();
m_fill = getPaintServer(state.fill(), state.fill_opacity());
m_stroke = getPaintServer(state.stroke(), state.stroke_opacity());
m_baseline_shit = state.baseline_shit();
SVGGraphicsElement::layoutElement(state);

LengthContext lengthContext(this);
Expand Down
2 changes: 2 additions & 0 deletions source/svgtextelement.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class SVGTextPositioningElement : public SVGGraphicsElement {
const Font& font() const { return m_font; }
const SVGPaintServer& fill() const { return m_fill; }
const SVGPaintServer& stroke() const { return m_stroke; }
const BaselineShift& baseline_shit() const { return m_baseline_shit; }

float stroke_width() const { return m_stroke_width; }
TextAnchor text_anchor() const { return m_text_anchor; }
Expand All @@ -98,6 +99,7 @@ class SVGTextPositioningElement : public SVGGraphicsElement {
Font m_font;
SVGPaintServer m_fill;
SVGPaintServer m_stroke;
BaselineShift m_baseline_shit;

float m_stroke_width = 1.f;
TextAnchor m_text_anchor = TextAnchor::Start;
Expand Down

0 comments on commit ba15dbc

Please sign in to comment.