Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Private Member Functions | List of all members
SkSVGTextContext Class Referencefinal

#include <SkSVGTextPriv.h>

Inheritance diagram for SkSVGTextContext:
SkShaper::RunHandler

Classes

class  PosAttrs
 
class  ScopedPosResolver
 

Public Types

using ShapedTextCallback = std::function< void(const SkSVGRenderContext &, const sk_sp< SkTextBlob > &, const SkPaint *, const SkPaint *)>
 

Public Member Functions

 SkSVGTextContext (const SkSVGRenderContext &, const ShapedTextCallback &, const SkSVGTextPath *=nullptr)
 
 ~SkSVGTextContext () override
 
void shapeFragment (const SkString &, const SkSVGRenderContext &, SkSVGXmlSpace)
 
void flushChunk (const SkSVGRenderContext &ctx)
 
const ShapedTextCallbackgetCallback () const
 

Private Member Functions

void beginLine () override
 
void runInfo (const RunInfo &) override
 
void commitRunInfo () override
 
Buffer runBuffer (const RunInfo &ri) override
 
void commitRunBuffer (const RunInfo &ri) override
 
void commitLine () override
 

Detailed Description

Definition at line 34 of file SkSVGTextPriv.h.

Member Typedef Documentation

◆ ShapedTextCallback

using SkSVGTextContext::ShapedTextCallback = std::function<void(const SkSVGRenderContext&, const sk_sp<SkTextBlob>&, const SkPaint*, const SkPaint*)>

Definition at line 36 of file SkSVGTextPriv.h.

Constructor & Destructor Documentation

◆ SkSVGTextContext()

SkSVGTextContext::SkSVGTextContext ( const SkSVGRenderContext ctx,
const ShapedTextCallback cb,
const SkSVGTextPath tpath = nullptr 
)

Definition at line 274 of file SkSVGText.cpp.

277 : fRenderContext(ctx)
278 , fCallback(cb)
279 , fShaper(ctx.makeShaper())
280 , fChunkAlignmentFactor(ComputeAlignmentFactor(ctx.presentationContext())) {
281 // If the shaper callback returns null, fallback to the primitive shaper and
282 // signal that we should not use the other callbacks in shapePendingBuffer
283 if (!fShaper) {
284 fShaper = SkShapers::Primitive::PrimitiveText();
285 fForcePrimitiveShaping = true;
286 }
287 if (tpath) {
288 fPathData = std::make_unique<PathData>(ctx, *tpath);
289
290 // https://www.w3.org/TR/SVG11/text.html#TextPathElementStartOffsetAttribute
291 auto resolve_offset = [this](const SkSVGLength& offset) {
293 // "If a <length> other than a percentage is given, then the ‘startOffset’
294 // represents a distance along the path measured in the current user coordinate
295 // system."
296 return fRenderContext.lengthContext()
298 }
299
300 // "If a percentage is given, then the ‘startOffset’ represents a percentage distance
301 // along the entire path."
302 return offset.value() * fPathData->length() / 100;
303 };
304
305 // startOffset acts as an initial absolute position
306 fChunkPos.fX = resolve_offset(tpath->getStartOffset());
307 }
308}
SkScalar resolve(const SkSVGLength &, LengthType) const
const SkSVGPresentationContext & presentationContext() const
const SkSVGLengthContext & lengthContext() const
std::unique_ptr< SkShaper > makeShaper() const
Point offset
float fX
x-axis value

◆ ~SkSVGTextContext()

SkSVGTextContext::~SkSVGTextContext ( )
override

Definition at line 310 of file SkSVGText.cpp.

310 {
311 this->flushChunk(fRenderContext);
312}
void flushChunk(const SkSVGRenderContext &ctx)

Member Function Documentation

◆ beginLine()

void SkSVGTextContext::beginLine ( )
inlineoverrideprivatevirtual

Called when beginning a line.

Implements SkShaper::RunHandler.

Definition at line 177 of file SkSVGTextPriv.h.

177{}

◆ commitLine()

void SkSVGTextContext::commitLine ( )
overrideprivatevirtual

Called when ending a line.

Implements SkShaper::RunHandler.

Definition at line 524 of file SkSVGText.cpp.

524 {
525 if (!fShapeBuffer.fUtf8PosAdjust.empty()) {
526 // Offset adjustments are cumulative - only advance the current chunk with the last value.
527 fChunkAdvance += fShapeBuffer.fUtf8PosAdjust.back().offset;
528 }
529}

◆ commitRunBuffer()

void SkSVGTextContext::commitRunBuffer ( const RunInfo info)
overrideprivatevirtual

Called after each runBuffer is filled out.

Implements SkShaper::RunHandler.

Definition at line 512 of file SkSVGText.cpp.

512 {
513 const auto& current_run = fRuns.back();
514
515 // stash position adjustments
516 for (size_t i = 0; i < ri.glyphCount; ++i) {
517 const auto utf8_index = fShapeClusterBuffer[i];
518 current_run.glyhPosAdjust[i] = fShapeBuffer.fUtf8PosAdjust[SkToInt(utf8_index)];
519 }
520
521 fChunkAdvance += ri.fAdvance;
522}
constexpr int SkToInt(S x)
Definition SkTo.h:29

◆ commitRunInfo()

void SkSVGTextContext::commitRunInfo ( )
inlineoverrideprivatevirtual

Called after all runInfo calls for a line.

Implements SkShaper::RunHandler.

Definition at line 179 of file SkSVGTextPriv.h.

179{}

◆ flushChunk()

void SkSVGTextContext::flushChunk ( const SkSVGRenderContext ctx)

Definition at line 463 of file SkSVGText.cpp.

463 {
464 SkTextBlobBuilder blobBuilder;
465
466 for (const auto& run : fRuns) {
467 const auto& buf = blobBuilder.allocRunRSXform(run.font, SkToInt(run.glyphCount));
468 std::copy(run.glyphs.get(), run.glyphs.get() + run.glyphCount, buf.glyphs);
469 for (size_t i = 0; i < run.glyphCount; ++i) {
470 buf.xforms()[i] = this->computeGlyphXform(run.glyphs[i],
471 run.font,
472 run.glyphPos[i],
473 run.glyhPosAdjust[i]);
474 }
475
476 fCallback(ctx, blobBuilder.make(), run.fillPaint.get(), run.strokePaint.get());
477 }
478
479 fChunkPos += fChunkAdvance;
480 fChunkAdvance = {0,0};
481 fChunkAlignmentFactor = ComputeAlignmentFactor(ctx.presentationContext());
482
483 fRuns.clear();
484}
const RunBuffer & allocRunRSXform(const SkFont &font, int count)
sk_sp< SkTextBlob > make()
Definition run.py:1

◆ getCallback()

const ShapedTextCallback & SkSVGTextContext::getCallback ( ) const
inline

Definition at line 120 of file SkSVGTextPriv.h.

120{ return fCallback; }

◆ runBuffer()

SkShaper::RunHandler::Buffer SkSVGTextContext::runBuffer ( const RunInfo info)
overrideprivatevirtual

Called for each run in a line after commitRunInfo. The buffer will be filled out.

Implements SkShaper::RunHandler.

Definition at line 486 of file SkSVGText.cpp.

486 {
487 SkASSERT(ri.glyphCount);
488
489 fRuns.push_back({
490 ri.fFont,
491 fCurrentFill.isValid() ? std::make_unique<SkPaint>(*fCurrentFill) : nullptr,
492 fCurrentStroke.isValid() ? std::make_unique<SkPaint>(*fCurrentStroke) : nullptr,
493 std::make_unique<SkGlyphID[] >(ri.glyphCount),
494 std::make_unique<SkPoint[] >(ri.glyphCount),
495 std::make_unique<PositionAdjustment[]>(ri.glyphCount),
496 ri.glyphCount,
497 ri.fAdvance,
498 });
499
500 // Ensure sufficient space to temporarily fetch cluster information.
501 fShapeClusterBuffer.resize(std::max(fShapeClusterBuffer.size(), ri.glyphCount));
502
503 return {
504 fRuns.back().glyphs.get(),
505 fRuns.back().glyphPos.get(),
506 nullptr,
507 fShapeClusterBuffer.data(),
508 fChunkAdvance,
509 };
510}
#define SkASSERT(cond)
Definition SkAssert.h:116
uint16_t SkGlyphID
Definition SkTypes.h:179
bool isValid() const
Definition SkTLazy.h:77
Definition ref_ptr.h:256

◆ runInfo()

void SkSVGTextContext::runInfo ( const RunInfo info)
inlineoverrideprivatevirtual

Called once for each run in a line. Can compute baselines and offsets.

Implements SkShaper::RunHandler.

Definition at line 178 of file SkSVGTextPriv.h.

178{}

◆ shapeFragment()

void SkSVGTextContext::shapeFragment ( const SkString txt,
const SkSVGRenderContext ctx,
SkSVGXmlSpace  xs 
)

Definition at line 314 of file SkSVGText.cpp.

315 {
316 // https://www.w3.org/TR/SVG11/text.html#WhiteSpace
317 // https://www.w3.org/TR/2008/REC-xml-20081126/#NT-S
318 auto filterWSDefault = [this](SkUnichar ch) -> SkUnichar {
319 // Remove all newline chars.
320 if (ch == '\n') {
321 return -1;
322 }
323
324 // Convert tab chars to space.
325 if (ch == '\t') {
326 ch = ' ';
327 }
328
329 // Consolidate contiguous space chars and strip leading spaces (fPrevCharSpace
330 // starts off as true).
331 if (fPrevCharSpace && ch == ' ') {
332 return -1;
333 }
334
335 // TODO: Strip trailing WS? Doing this across chunks would require another buffering
336 // layer. In general, trailing WS should have no rendering side effects. Skipping
337 // for now.
338 return ch;
339 };
340 auto filterWSPreserve = [](SkUnichar ch) -> SkUnichar {
341 // Convert newline and tab chars to space.
342 if (ch == '\n' || ch == '\t') {
343 ch = ' ';
344 }
345 return ch;
346 };
347
348 // Stash paints for access from SkShaper callbacks.
349 fCurrentFill = ctx.fillPaint();
350 fCurrentStroke = ctx.strokePaint();
351
352 const auto font = ResolveFont(ctx);
353 fShapeBuffer.reserve(txt.size());
354
355 const char* ch_ptr = txt.c_str();
356 const char* ch_end = ch_ptr + txt.size();
357
358 while (ch_ptr < ch_end) {
359 auto ch = SkUTF::NextUTF8(&ch_ptr, ch_end);
360 ch = (xs == SkSVGXmlSpace::kDefault)
361 ? filterWSDefault(ch)
362 : filterWSPreserve(ch);
363
364 if (ch < 0) {
365 // invalid utf or char filtered out
366 continue;
367 }
368
369 SkASSERT(fPosResolver);
370 const auto pos = fPosResolver->resolve(fCurrentCharIndex++);
371
372 // Absolute position adjustments define a new chunk.
373 // (https://www.w3.org/TR/SVG11/text.html#TextLayoutIntroduction)
374 if (pos.has(PosAttrs::kX) || pos.has(PosAttrs::kY)) {
375 this->shapePendingBuffer(ctx, font);
376 this->flushChunk(ctx);
377
378 // New chunk position.
379 if (pos.has(PosAttrs::kX)) {
380 fChunkPos.fX = pos[PosAttrs::kX];
381 }
382 if (pos.has(PosAttrs::kY)) {
383 fChunkPos.fY = pos[PosAttrs::kY];
384 }
385 }
386
387 fShapeBuffer.append(ch, {
388 {
390 pos.has(PosAttrs::kDy) ? pos[PosAttrs::kDy] : 0,
391 },
392 pos.has(PosAttrs::kRotate) ? SkDegreesToRadians(pos[PosAttrs::kRotate]) : 0,
393 });
394
395 fPrevCharSpace = (ch == ' ');
396 }
397
398 this->shapePendingBuffer(ctx, font);
399
400 // Note: at this point we have shaped and buffered RunRecs for the current fragment.
401 // The active text chunk continues until an explicit or implicit flush.
402}
SkPoint pos
#define SkDegreesToRadians(degrees)
Definition SkScalar.h:77
int32_t SkUnichar
Definition SkTypes.h:175
SkTLazy< SkPaint > fillPaint() const
SkTLazy< SkPaint > strokePaint() const
PosAttrs resolve(size_t charIndex) const
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
Definition SkUTF.cpp:118
font
Font Metadata and Metrics.
float fY
y-axis value

The documentation for this class was generated from the following files: