Commit 67b9f6e7 authored by eae's avatar eae Committed by Commit bot

[LayoutNG] Add NG-specific DrawText support to GraphicsContext

Add LayoutNG versions of the DrawText and DrawEmphasisMarks methods that
operate on TextFragmentPaintInfo instances (wrapping text fragment data)
instead of TextRunPaintInfo instances. Reuses impl when at all possible.

Also adds support for bloberizing emphasis marks for text fragments with
the addition of a FillTextEmphasisGlyphs StringView/ShapeResult version.

BUG=714962
R=kojii@chromium.org

Review-Url: https://codereview.chromium.org/2845883002
Cr-Commit-Position: refs/heads/master@{#467592}
parent b7bd7c79
...@@ -246,6 +246,27 @@ void Font::DrawEmphasisMarks(PaintCanvas* canvas, ...@@ -246,6 +246,27 @@ void Font::DrawEmphasisMarks(PaintCanvas* canvas,
DrawBlobs(canvas, flags, bloberizer.Blobs(), point); DrawBlobs(canvas, flags, bloberizer.Blobs(), point);
} }
void Font::DrawEmphasisMarks(PaintCanvas* canvas,
const TextFragmentPaintInfo& text_info,
const AtomicString& mark,
const FloatPoint& point,
float device_scale_factor,
const PaintFlags& flags) const {
if (ShouldSkipDrawing())
return;
FontCachePurgePreventer purge_preventer;
const auto emphasis_glyph_data = GetEmphasisMarkGlyphData(mark);
if (!emphasis_glyph_data.font_data)
return;
ShapeResultBloberizer bloberizer(*this, device_scale_factor);
bloberizer.FillTextEmphasisGlyphs(
text_info.text, text_info.direction, text_info.from, text_info.to,
emphasis_glyph_data, text_info.shape_result);
DrawBlobs(canvas, flags, bloberizer.Blobs(), point);
}
float Font::Width(const TextRun& run, float Font::Width(const TextRun& run,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds) const { FloatRect* glyph_bounds) const {
......
...@@ -60,6 +60,7 @@ struct TextRunPaintInfo; ...@@ -60,6 +60,7 @@ struct TextRunPaintInfo;
// TODO(eae): Move to a separate file? // TODO(eae): Move to a separate file?
struct PLATFORM_EXPORT TextFragmentPaintInfo { struct PLATFORM_EXPORT TextFragmentPaintInfo {
const StringView text; const StringView text;
TextDirection direction;
unsigned from; unsigned from;
unsigned to; unsigned to;
const ShapeResult* shape_result; const ShapeResult* shape_result;
...@@ -111,6 +112,12 @@ class PLATFORM_EXPORT Font { ...@@ -111,6 +112,12 @@ class PLATFORM_EXPORT Font {
const FloatPoint&, const FloatPoint&,
float device_scale_factor, float device_scale_factor,
const PaintFlags&) const; const PaintFlags&) const;
void DrawEmphasisMarks(PaintCanvas*,
const TextFragmentPaintInfo&,
const AtomicString& mark,
const FloatPoint&,
float device_scale_factor,
const PaintFlags&) const;
struct TextIntercept { struct TextIntercept {
float begin_, end_; float begin_, end_;
......
...@@ -147,14 +147,31 @@ void ShapeResultBloberizer::FillTextEmphasisGlyphs( ...@@ -147,14 +147,31 @@ void ShapeResultBloberizer::FillTextEmphasisGlyphs(
for (unsigned i = 0; i < word_result->runs_.size(); i++) { for (unsigned i = 0; i < word_result->runs_.size(); i++) {
unsigned resolved_offset = unsigned resolved_offset =
word_offset - (run_info.run.Rtl() ? word_result->NumCharacters() : 0); word_offset - (run_info.run.Rtl() ? word_result->NumCharacters() : 0);
advance += advance += FillTextEmphasisGlyphsForRun(
FillTextEmphasisGlyphsForRun(word_result->runs_[i].get(), run_info, word_result->runs_[i].get(), run_info.run,
emphasis_data, advance, resolved_offset); run_info.run.CharactersLength(), run_info.run.Direction(),
run_info.from, run_info.to, emphasis_data, advance, resolved_offset);
} }
word_offset += word_result->NumCharacters() * (run_info.run.Rtl() ? -1 : 1); word_offset += word_result->NumCharacters() * (run_info.run.Rtl() ? -1 : 1);
} }
} }
void ShapeResultBloberizer::FillTextEmphasisGlyphs(const StringView& text,
TextDirection direction,
unsigned from,
unsigned to,
const GlyphData& emphasis,
const ShapeResult* result) {
float advance = 0;
unsigned offset = 0;
for (unsigned i = 0; i < result->runs_.size(); i++) {
advance += FillTextEmphasisGlyphsForRun(result->runs_[i].get(), text,
text.length(), direction, from, to,
emphasis, advance, offset);
}
}
namespace { namespace {
template <typename TextContainerType> template <typename TextContainerType>
...@@ -307,9 +324,14 @@ float ShapeResultBloberizer::FillFastHorizontalGlyphs( ...@@ -307,9 +324,14 @@ float ShapeResultBloberizer::FillFastHorizontalGlyphs(
return advance; return advance;
} }
template <typename TextContainerType>
float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun( float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun(
const ShapeResult::RunInfo* run, const ShapeResult::RunInfo* run,
const TextRunPaintInfo& run_info, const TextContainerType& text,
unsigned text_length,
TextDirection direction,
unsigned from,
unsigned to,
const GlyphData& emphasis_data, const GlyphData& emphasis_data,
float initial_advance, float initial_advance,
unsigned run_offset) { unsigned run_offset) {
...@@ -322,12 +344,6 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun( ...@@ -322,12 +344,6 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun(
FloatPoint glyph_center = FloatPoint glyph_center =
emphasis_data.font_data->BoundsForGlyph(emphasis_data.glyph).Center(); emphasis_data.font_data->BoundsForGlyph(emphasis_data.glyph).Center();
const auto& text_run = run_info.run;
const auto from = run_info.from;
const auto to = run_info.to;
TextDirection direction = text_run.Direction();
// A "cluster" in this context means a cluster as it is used by HarfBuzz: // A "cluster" in this context means a cluster as it is used by HarfBuzz:
// The minimal group of characters and corresponding glyphs, that cannot be // The minimal group of characters and corresponding glyphs, that cannot be
// broken down further from a text shaping point of view. A cluster can // broken down further from a text shaping point of view. A cluster can
...@@ -360,10 +376,9 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun( ...@@ -360,10 +376,9 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun(
cluster_advance += glyph_data.advance; cluster_advance += glyph_data.advance;
if (text_run.Is8Bit()) { if (text.Is8Bit()) {
float glyph_advance_x = glyph_data.advance; float glyph_advance_x = glyph_data.advance;
if (Character::CanReceiveTextEmphasis( if (Character::CanReceiveTextEmphasis(text[current_character_index])) {
text_run[current_character_index])) {
AddEmphasisMark(*this, emphasis_data, glyph_center, AddEmphasisMark(*this, emphasis_data, glyph_center,
advance_so_far + glyph_advance_x / 2); advance_so_far + glyph_advance_x / 2);
} }
...@@ -378,8 +393,7 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun( ...@@ -378,8 +393,7 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun(
: run->GlyphToCharacterIndex(i + 1) + run_offset); : run->GlyphToCharacterIndex(i + 1) + run_offset);
} }
graphemes_in_cluster = CountGraphemesInCluster( graphemes_in_cluster = CountGraphemesInCluster(
text_run.Characters16(), text_run.CharactersLength(), cluster_start, text.Characters16(), text_length, cluster_start, cluster_end);
cluster_end);
if (!graphemes_in_cluster || !cluster_advance) if (!graphemes_in_cluster || !cluster_advance)
continue; continue;
...@@ -387,8 +401,7 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun( ...@@ -387,8 +401,7 @@ float ShapeResultBloberizer::FillTextEmphasisGlyphsForRun(
for (unsigned j = 0; j < graphemes_in_cluster; ++j) { for (unsigned j = 0; j < graphemes_in_cluster; ++j) {
// Do not put emphasis marks on space, separator, and control // Do not put emphasis marks on space, separator, and control
// characters. // characters.
if (Character::CanReceiveTextEmphasis( if (Character::CanReceiveTextEmphasis(text[current_character_index])) {
text_run[current_character_index])) {
AddEmphasisMark(*this, emphasis_data, glyph_center, AddEmphasisMark(*this, emphasis_data, glyph_center,
advance_so_far + glyph_advance_x / 2); advance_so_far + glyph_advance_x / 2);
} }
......
...@@ -39,6 +39,12 @@ class PLATFORM_EXPORT ShapeResultBloberizer { ...@@ -39,6 +39,12 @@ class PLATFORM_EXPORT ShapeResultBloberizer {
void FillTextEmphasisGlyphs(const TextRunPaintInfo&, void FillTextEmphasisGlyphs(const TextRunPaintInfo&,
const GlyphData& emphasis_data, const GlyphData& emphasis_data,
const ShapeResultBuffer&); const ShapeResultBuffer&);
void FillTextEmphasisGlyphs(const StringView&,
TextDirection,
unsigned from,
unsigned to,
const GlyphData& emphasis_data,
const ShapeResult*);
void Add(Glyph glyph, const SimpleFontData* font_data, float h_offset) { void Add(Glyph glyph, const SimpleFontData* font_data, float h_offset) {
// cannot mix x-only/xy offsets // cannot mix x-only/xy offsets
...@@ -110,8 +116,13 @@ class PLATFORM_EXPORT ShapeResultBloberizer { ...@@ -110,8 +116,13 @@ class PLATFORM_EXPORT ShapeResultBloberizer {
float FillFastHorizontalGlyphs(const ShapeResultBuffer&, TextDirection); float FillFastHorizontalGlyphs(const ShapeResultBuffer&, TextDirection);
float FillFastHorizontalGlyphs(const ShapeResult*, float advance = 0); float FillFastHorizontalGlyphs(const ShapeResult*, float advance = 0);
template <typename TextContainerType>
float FillTextEmphasisGlyphsForRun(const ShapeResult::RunInfo*, float FillTextEmphasisGlyphsForRun(const ShapeResult::RunInfo*,
const TextRunPaintInfo&, const TextContainerType&,
unsigned text_length,
TextDirection,
unsigned from,
unsigned to,
const GlyphData& emphasis_data, const GlyphData& emphasis_data,
float initial_advance, float initial_advance,
unsigned run_offset); unsigned run_offset);
......
...@@ -739,17 +739,32 @@ void GraphicsContext::DrawRect(const IntRect& rect) { ...@@ -739,17 +739,32 @@ void GraphicsContext::DrawRect(const IntRect& rect) {
} }
} }
void GraphicsContext::DrawText(const Font& font, template <typename TextPaintInfo>
const TextRunPaintInfo& run_info, void GraphicsContext::DrawTextInternal(const Font& font,
const FloatPoint& point, const TextPaintInfo& text_info,
const PaintFlags& flags) { const FloatPoint& point,
const PaintFlags& flags) {
if (ContextDisabled()) if (ContextDisabled())
return; return;
if (font.DrawText(canvas_, run_info, point, device_scale_factor_, flags)) if (font.DrawText(canvas_, text_info, point, device_scale_factor_, flags))
paint_controller_.SetTextPainted(); paint_controller_.SetTextPainted();
} }
void GraphicsContext::DrawText(const Font& font,
const TextRunPaintInfo& text_info,
const FloatPoint& point,
const PaintFlags& flags) {
DrawTextInternal(font, text_info, point, flags);
}
void GraphicsContext::DrawText(const Font& font,
const TextFragmentPaintInfo& text_info,
const FloatPoint& point,
const PaintFlags& flags) {
DrawTextInternal(font, text_info, point, flags);
}
template <typename DrawTextFunc> template <typename DrawTextFunc>
void GraphicsContext::DrawTextPasses(const DrawTextFunc& draw_text) { void GraphicsContext::DrawTextPasses(const DrawTextFunc& draw_text) {
TextDrawingModeFlags mode_flags = TextDrawingMode(); TextDrawingModeFlags mode_flags = TextDrawingMode();
...@@ -769,32 +784,60 @@ void GraphicsContext::DrawTextPasses(const DrawTextFunc& draw_text) { ...@@ -769,32 +784,60 @@ void GraphicsContext::DrawTextPasses(const DrawTextFunc& draw_text) {
} }
} }
void GraphicsContext::DrawText(const Font& font, template <typename TextPaintInfo>
const TextRunPaintInfo& run_info, void GraphicsContext::DrawTextInternal(const Font& font,
const FloatPoint& point) { const TextPaintInfo& text_info,
const FloatPoint& point) {
if (ContextDisabled()) if (ContextDisabled())
return; return;
DrawTextPasses([&font, &run_info, &point, this](const PaintFlags& flags) { DrawTextPasses([&font, &text_info, &point, this](const PaintFlags& flags) {
if (font.DrawText(canvas_, run_info, point, device_scale_factor_, flags)) if (font.DrawText(canvas_, text_info, point, device_scale_factor_, flags))
paint_controller_.SetTextPainted(); paint_controller_.SetTextPainted();
}); });
} }
void GraphicsContext::DrawEmphasisMarks(const Font& font, void GraphicsContext::DrawText(const Font& font,
const TextRunPaintInfo& run_info, const TextRunPaintInfo& text_info,
const AtomicString& mark, const FloatPoint& point) {
const FloatPoint& point) { DrawTextInternal(font, text_info, point);
}
void GraphicsContext::DrawText(const Font& font,
const TextFragmentPaintInfo& text_info,
const FloatPoint& point) {
DrawTextInternal(font, text_info, point);
}
template <typename TextPaintInfo>
void GraphicsContext::DrawEmphasisMarksInternal(const Font& font,
const TextPaintInfo& text_info,
const AtomicString& mark,
const FloatPoint& point) {
if (ContextDisabled()) if (ContextDisabled())
return; return;
DrawTextPasses( DrawTextPasses(
[&font, &run_info, &mark, &point, this](const PaintFlags& flags) { [&font, &text_info, &mark, &point, this](const PaintFlags& flags) {
font.DrawEmphasisMarks(canvas_, run_info, mark, point, font.DrawEmphasisMarks(canvas_, text_info, mark, point,
device_scale_factor_, flags); device_scale_factor_, flags);
}); });
} }
void GraphicsContext::DrawEmphasisMarks(const Font& font,
const TextRunPaintInfo& text_info,
const AtomicString& mark,
const FloatPoint& point) {
DrawEmphasisMarksInternal(font, text_info, mark, point);
}
void GraphicsContext::DrawEmphasisMarks(const Font& font,
const TextFragmentPaintInfo& text_info,
const AtomicString& mark,
const FloatPoint& point) {
DrawEmphasisMarksInternal(font, text_info, mark, point);
}
void GraphicsContext::DrawBidiText( void GraphicsContext::DrawBidiText(
const Font& font, const Font& font,
const TextRunPaintInfo& run_info, const TextRunPaintInfo& run_info,
......
...@@ -237,14 +237,26 @@ class PLATFORM_EXPORT GraphicsContext { ...@@ -237,14 +237,26 @@ class PLATFORM_EXPORT GraphicsContext {
SkClipOp = SkClipOp::kIntersect); SkClipOp = SkClipOp::kIntersect);
void DrawText(const Font&, const TextRunPaintInfo&, const FloatPoint&); void DrawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
void DrawText(const Font&, const TextFragmentPaintInfo&, const FloatPoint&);
void DrawText(const Font&, void DrawText(const Font&,
const TextRunPaintInfo&, const TextRunPaintInfo&,
const FloatPoint&, const FloatPoint&,
const PaintFlags&); const PaintFlags&);
void DrawText(const Font&,
const TextFragmentPaintInfo&,
const FloatPoint&,
const PaintFlags&);
void DrawEmphasisMarks(const Font&, void DrawEmphasisMarks(const Font&,
const TextRunPaintInfo&, const TextRunPaintInfo&,
const AtomicString& mark, const AtomicString& mark,
const FloatPoint&); const FloatPoint&);
void DrawEmphasisMarks(const Font&,
const TextFragmentPaintInfo&,
const AtomicString& mark,
const FloatPoint&);
void DrawBidiText( void DrawBidiText(
const Font&, const Font&,
const TextRunPaintInfo&, const TextRunPaintInfo&,
...@@ -370,6 +382,21 @@ class PLATFORM_EXPORT GraphicsContext { ...@@ -370,6 +382,21 @@ class PLATFORM_EXPORT GraphicsContext {
return paint_state_; return paint_state_;
} }
template <typename TextPaintInfo>
void DrawTextInternal(const Font&,
const TextPaintInfo&,
const FloatPoint&,
const PaintFlags&);
template <typename TextPaintInfo>
void DrawTextInternal(const Font&, const TextPaintInfo&, const FloatPoint&);
template <typename TextPaintInfo>
void DrawEmphasisMarksInternal(const Font&,
const TextPaintInfo&,
const AtomicString& mark,
const FloatPoint&);
template <typename DrawTextFunc> template <typename DrawTextFunc>
void DrawTextPasses(const DrawTextFunc&); void DrawTextPasses(const DrawTextFunc&);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment