mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
LibWeb: Implement dominant-baseline for SVG text
This property determines the default baseline used to align content within the given box.
This commit is contained in:
committed by
Jelle Raaijmakers
parent
90a211bf47
commit
f05bc7c0cd
Notes:
github-actions[bot]
2026-02-26 08:24:27 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/f05bc7c0cd3 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8173 Reviewed-by: https://github.com/gmta ✅
62
Libraries/LibWeb/Layout/DominantBaseline.h
Normal file
62
Libraries/LibWeb/Layout/DominantBaseline.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Tim Ledbetter <tim.ledbetter@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/Font/Font.h>
|
||||
#include <LibWeb/CSS/ComputedValues.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
||||
// https://drafts.csswg.org/css-inline/#dominant-baseline-property
|
||||
static float dominant_baseline_offset(CSS::BaselineMetric metric, Gfx::FontPixelMetrics const& font_metrics)
|
||||
{
|
||||
switch (metric) {
|
||||
case CSS::BaselineMetric::Central:
|
||||
return (font_metrics.ascent - font_metrics.descent) / 2;
|
||||
case CSS::BaselineMetric::Middle:
|
||||
return font_metrics.x_height / 2;
|
||||
case CSS::BaselineMetric::Hanging:
|
||||
// FIXME: Read the hanging baseline from the font's BASE table.
|
||||
return font_metrics.ascent * 0.8f;
|
||||
case CSS::BaselineMetric::Ideographic:
|
||||
// FIXME: Read the ideographic baseline from the font's BASE table.
|
||||
return -font_metrics.descent;
|
||||
case CSS::BaselineMetric::Mathematical:
|
||||
// FIXME: Read the math baseline from the font's BASE table.
|
||||
return font_metrics.ascent * 0.5f;
|
||||
case CSS::BaselineMetric::TextTop:
|
||||
case CSS::BaselineMetric::TextBottom:
|
||||
// FIXME: Support text-top and text-bottom.
|
||||
case CSS::BaselineMetric::Alphabetic:
|
||||
return 0;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
static CSS::BaselineMetric resolve_dominant_baseline_metric(CSS::ComputedValues const& computed_values)
|
||||
{
|
||||
auto dominant_baseline = computed_values.dominant_baseline();
|
||||
if (dominant_baseline.has_value())
|
||||
return *dominant_baseline;
|
||||
|
||||
// https://drafts.csswg.org/css-inline/#valdef-dominant-baseline-auto
|
||||
// Equivalent to alphabetic in horizontal writing modes and in vertical writing modes when text-orientation is
|
||||
// sideways. Equivalent to central in vertical writing modes when text-orientation is mixed or upright.
|
||||
// FIXME: Take text-orientation into account once it is implemented.
|
||||
switch (computed_values.writing_mode()) {
|
||||
case CSS::WritingMode::HorizontalTb:
|
||||
case CSS::WritingMode::SidewaysRl:
|
||||
case CSS::WritingMode::SidewaysLr:
|
||||
return CSS::BaselineMetric::Alphabetic;
|
||||
case CSS::WritingMode::VerticalRl:
|
||||
case CSS::WritingMode::VerticalLr:
|
||||
return CSS::BaselineMetric::Central;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -893,6 +893,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
||||
computed_values.set_stop_opacity(computed_style.stop_opacity());
|
||||
|
||||
computed_values.set_text_anchor(computed_style.text_anchor());
|
||||
computed_values.set_dominant_baseline(computed_style.dominant_baseline());
|
||||
|
||||
// FIXME: Support calc()
|
||||
if (auto const& column_count = computed_style.property(CSS::PropertyID::ColumnCount); column_count.is_integer())
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <LibGfx/TextLayout.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/Layout/BlockFormattingContext.h>
|
||||
#include <LibWeb/Layout/DominantBaseline.h>
|
||||
#include <LibWeb/Layout/SVGClipBox.h>
|
||||
#include <LibWeb/Layout/SVGFormattingContext.h>
|
||||
#include <LibWeb/Layout/SVGGeometryBox.h>
|
||||
@@ -381,6 +382,9 @@ Gfx::Path SVGFormattingContext::compute_path_for_text(SVGTextBox const& text_box
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
auto baseline_metric = resolve_dominant_baseline_metric(text_box.computed_values());
|
||||
text_offset.translate_by(0, dominant_baseline_offset(baseline_metric, font.pixel_metrics()));
|
||||
|
||||
Gfx::Path path;
|
||||
path.move_to(text_offset);
|
||||
path.text(text_contents, font);
|
||||
|
||||
Reference in New Issue
Block a user