aa1b912046
Instead of unrolling blobs in SkCanvas, perform the equivalent ops in SkBaseDevice. This depends on https://codereview.chromium.org/511783005/. R=jvanverth@google.com, reed@google.com, robertphillips@google.com, bsalomon@google.com Author: fmalita@chromium.org Review URL: https://codereview.chromium.org/517663003
200 lines
6.6 KiB
C++
200 lines
6.6 KiB
C++
/*
|
|
* Copyright 2014 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef SkTextBlob_DEFINED
|
|
#define SkTextBlob_DEFINED
|
|
|
|
#include "SkPaint.h"
|
|
#include "SkRefCnt.h"
|
|
#include "SkTArray.h"
|
|
#include "SkTDArray.h"
|
|
|
|
class SkReadBuffer;
|
|
class SkWriteBuffer;
|
|
|
|
/** \class SkTextBlob
|
|
|
|
SkTextBlob combines multiple text runs into an immutable, ref-counted structure.
|
|
*/
|
|
class SK_API SkTextBlob : public SkRefCnt {
|
|
public:
|
|
/**
|
|
* Returns the blob bounding box.
|
|
*/
|
|
const SkRect& bounds() const { return fBounds; }
|
|
|
|
/**
|
|
* Return a non-zero, unique value representing the text blob.
|
|
*/
|
|
uint32_t uniqueID() const;
|
|
|
|
/**
|
|
* Serialize to a buffer.
|
|
*/
|
|
void flatten(SkWriteBuffer&) const;
|
|
|
|
/**
|
|
* Recreate an SkTextBlob that was serialized into a buffer.
|
|
*
|
|
* @param SkReadBuffer Serialized blob data.
|
|
* @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
|
|
* invalid.
|
|
*/
|
|
static const SkTextBlob* CreateFromBuffer(SkReadBuffer&);
|
|
|
|
private:
|
|
enum GlyphPositioning {
|
|
kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph.
|
|
kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph.
|
|
kFull_Positioning = 2 // Point positioning -- two scalars per glyph.
|
|
};
|
|
|
|
class RunIterator {
|
|
public:
|
|
RunIterator(const SkTextBlob* blob);
|
|
|
|
bool done() const;
|
|
void next();
|
|
|
|
uint32_t glyphCount() const;
|
|
const uint16_t* glyphs() const;
|
|
const SkScalar* pos() const;
|
|
const SkPoint& offset() const;
|
|
void applyFontToPaint(SkPaint*) const;
|
|
GlyphPositioning positioning() const;
|
|
|
|
private:
|
|
const SkTextBlob* fBlob;
|
|
int fIndex;
|
|
};
|
|
|
|
// A run is a sequence of glyphs sharing the same font metrics and positioning mode.
|
|
struct Run {
|
|
uint32_t count;
|
|
uint32_t glyphStart; // index into fGlyphBuffer
|
|
uint32_t posStart; // index into fPosBuffer
|
|
SkPoint offset; // run offset (unsued for fully positioned glyphs)
|
|
SkPaint font;
|
|
GlyphPositioning positioning;
|
|
};
|
|
|
|
SkTextBlob(uint16_t* glyphs, SkScalar* pos, const SkTArray<Run>* runs, const SkRect& bounds);
|
|
|
|
static unsigned ScalarsPerGlyph(GlyphPositioning pos);
|
|
|
|
friend class SkBaseDevice;
|
|
friend class SkTextBlobBuilder;
|
|
friend class TextBlobTester;
|
|
|
|
const SkAutoTMalloc<uint16_t> fGlyphBuffer;
|
|
const SkAutoTMalloc<SkScalar> fPosBuffer;
|
|
|
|
// SkTArray required here for run font destruction.
|
|
SkAutoTDelete<const SkTArray<Run> > fRuns;
|
|
const SkRect fBounds;
|
|
|
|
mutable uint32_t fUniqueID;
|
|
|
|
typedef SkRefCnt INHERITED;
|
|
};
|
|
|
|
/** \class SkTextBlobBuilder
|
|
|
|
Helper class for constructing SkTextBlobs.
|
|
*/
|
|
class SK_API SkTextBlobBuilder {
|
|
public:
|
|
/**
|
|
* @param runs The number of runs to be added, if known. This is a storage hint and
|
|
* not a limit.
|
|
*/
|
|
SkTextBlobBuilder(unsigned runs = 0);
|
|
|
|
~SkTextBlobBuilder();
|
|
|
|
/**
|
|
* Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
|
|
* can be reused.
|
|
*/
|
|
const SkTextBlob* build();
|
|
|
|
/**
|
|
* Glyph and position buffers associated with a run.
|
|
*
|
|
* A run is a sequence of glyphs sharing the same font metrics and positioning mode.
|
|
*/
|
|
struct RunBuffer {
|
|
uint16_t* glyphs;
|
|
SkScalar* pos;
|
|
};
|
|
|
|
/**
|
|
* Allocates a new default-positioned run and returns its writable glyph buffer
|
|
* for direct manipulation.
|
|
*
|
|
* @param font The font to be used for this run.
|
|
* @param count Number of glyphs.
|
|
* @param x,y Position within the blob.
|
|
* @param bounds Optional run bounding box. If known in advance (!= NULL), it will
|
|
* be used when computing the blob bounds, to avoid re-measuring.
|
|
*
|
|
* @return A writable glyph buffer, valid until the next allocRun() or
|
|
* build() call. The buffer is guaranteed to hold @count@ glyphs.
|
|
*/
|
|
const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
|
|
const SkRect* bounds = NULL);
|
|
|
|
/**
|
|
* Allocates a new horizontally-positioned run and returns its writable glyph and position
|
|
* buffers for direct manipulation.
|
|
*
|
|
* @param font The font to be used for this run.
|
|
* @param count Number of glyphs.
|
|
* @param y Vertical offset within the blob.
|
|
* @param bounds Optional run bounding box. If known in advance (!= NULL), it will
|
|
* be used when computing the blob bounds, to avoid re-measuring.
|
|
*
|
|
* @return Writable glyph and position buffers, valid until the next allocRun()
|
|
* or build() call. The buffers are guaranteed to hold @count@ elements.
|
|
*/
|
|
const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
|
|
const SkRect* bounds = NULL);
|
|
|
|
/**
|
|
* Allocates a new fully-positioned run and returns its writable glyph and position
|
|
* buffers for direct manipulation.
|
|
*
|
|
* @param font The font to be used for this run.
|
|
* @param count Number of glyphs.
|
|
* @param bounds Optional run bounding box. If known in advance (!= NULL), it will
|
|
* be used when computing the blob bounds, to avoid re-measuring.
|
|
*
|
|
* @return Writable glyph and position buffers, valid until the next allocRun()
|
|
* or build() call. The glyph buffer and position buffer are
|
|
* guaranteed to hold @count@ and 2 * @count@ elements, respectively.
|
|
*/
|
|
const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
|
|
|
|
private:
|
|
void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
|
|
int count, SkPoint offset, const SkRect* bounds);
|
|
void ensureRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
|
|
const SkPoint& offset);
|
|
void updateDeferredBounds();
|
|
|
|
SkTDArray<uint16_t> fGlyphBuffer;
|
|
SkTDArray<SkScalar> fPosBuffer;
|
|
SkTArray<SkTextBlob::Run>* fRuns;
|
|
|
|
SkRect fBounds;
|
|
bool fDeferredBounds;
|
|
|
|
RunBuffer fCurrentRunBuffer;
|
|
};
|
|
|
|
#endif // SkTextBlob_DEFINED
|