SkPDF: clean up fRasterDpi
- PDFDevice no longer has a fRasterDpi; simply queries document. - #define DPI_FOR_RASTER_SCALE_ONE becomes constexpr float. - PDFShader::GetPDFShader no longer takes rasterScale or dpi - Remove un-needed factory functions. We're all adults here. Change-Id: Id2ce75d4e61af385763ccfb1db210465a1600067 Reviewed-on: https://skia-review.googlesource.com/21348 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Hal Canary <halcanary@google.com>
This commit is contained in:
parent
1c9686bfa5
commit
a062258e76
@ -216,10 +216,9 @@ struct PDFShaderBench : public Benchmark {
|
||||
SkNullWStream nullStream;
|
||||
SkPDFDocument doc(&nullStream, nullptr, 72,
|
||||
SkDocument::PDFMetadata(), nullptr, false);
|
||||
sk_sp<SkPDFObject> shader(
|
||||
SkPDFShader::GetPDFShader(
|
||||
&doc, 72, fShader.get(), SkMatrix::I(),
|
||||
SkIRect::MakeWH(400,400), 72));
|
||||
sk_sp<SkPDFObject> shader =
|
||||
SkPDFShader::GetPDFShader(&doc, fShader.get(), SkMatrix::I(),
|
||||
SkIRect::MakeWH(400,400));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -58,8 +58,6 @@
|
||||
// encoding.
|
||||
#endif
|
||||
|
||||
#define DPI_FOR_RASTER_SCALE_ONE 72
|
||||
|
||||
// Utility functions
|
||||
|
||||
// This function destroys the mask and either frees or takes the pixels.
|
||||
@ -460,13 +458,11 @@ SkBaseDevice* SkPDFDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
|
||||
return SkBitmapDevice::Create(cinfo.fInfo, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
|
||||
}
|
||||
SkISize size = SkISize::Make(cinfo.fInfo.width(), cinfo.fInfo.height());
|
||||
return SkPDFDevice::Make(size, fRasterDpi, fDocument).release();
|
||||
return new SkPDFDevice(size, fDocument);
|
||||
}
|
||||
|
||||
SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); }
|
||||
|
||||
|
||||
|
||||
// A helper class to automatically finish a ContentEntry at the end of a
|
||||
// drawing method and maintain the state needed between set up and finish.
|
||||
class ScopedContentEntry {
|
||||
@ -549,25 +545,24 @@ private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* doc, bool flip)
|
||||
SkPDFDevice::SkPDFDevice(SkISize pageSize, SkPDFDocument* doc)
|
||||
: INHERITED(SkImageInfo::MakeUnknown(pageSize.width(), pageSize.height()),
|
||||
SkSurfaceProps(0, kUnknown_SkPixelGeometry))
|
||||
, fPageSize(pageSize)
|
||||
, fRasterDpi(rasterDpi)
|
||||
, fDocument(doc) {
|
||||
, fInitialTransform(SkMatrix::I())
|
||||
, fDocument(doc)
|
||||
{
|
||||
SkASSERT(pageSize.width() > 0);
|
||||
SkASSERT(pageSize.height() > 0);
|
||||
}
|
||||
|
||||
if (flip) {
|
||||
// Skia generally uses the top left as the origin but PDF
|
||||
// natively has the origin at the bottom left. This matrix
|
||||
// corrects for that. But that only needs to be done once, we
|
||||
// don't do it when layering.
|
||||
fInitialTransform.setTranslate(0, SkIntToScalar(pageSize.fHeight));
|
||||
fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
|
||||
} else {
|
||||
fInitialTransform.setIdentity();
|
||||
}
|
||||
void SkPDFDevice::setFlip() {
|
||||
// Skia generally uses the top left as the origin but PDF
|
||||
// natively has the origin at the bottom left. This matrix
|
||||
// corrects for that. But that only needs to be done once, we
|
||||
// don't do it when layering.
|
||||
fInitialTransform.setTranslate(0, SkIntToScalar(fPageSize.fHeight));
|
||||
fInitialTransform.preScale(SK_Scalar1, -SK_Scalar1);
|
||||
}
|
||||
|
||||
SkPDFDevice::~SkPDFDevice() {
|
||||
@ -845,8 +840,8 @@ void SkPDFDevice::internalDrawPathWithFilter(const SkClipStack& clipStack,
|
||||
: SkStrokeRec::kHairline_InitStyle;
|
||||
path.transform(ctm, &path);
|
||||
|
||||
// TODO(halcanary): respect fRasterDpi.
|
||||
// SkScalar rasterScale = (float)fRasterDpi / DPI_FOR_RASTER_SCALE_ONE;
|
||||
// TODO(halcanary): respect fDocument->rasterDpi().
|
||||
// SkScalar rasterScale = (float)rasterDpi / SkPDFUtils::kDpiForRasterScaleOne;
|
||||
// Would it be easier to just change the device size (and pre-scale the canvas)?
|
||||
SkIRect bounds = clipStack.bounds(size(*this)).roundOut();
|
||||
SkMask sourceMask;
|
||||
@ -2177,10 +2172,7 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint(
|
||||
SkIRect bounds;
|
||||
clipStackBounds.roundOut(&bounds);
|
||||
|
||||
SkScalar rasterScale =
|
||||
SkIntToScalar(fRasterDpi) / DPI_FOR_RASTER_SCALE_ONE;
|
||||
pdfShader = SkPDFShader::GetPDFShader(
|
||||
fDocument, fRasterDpi, shader, transform, bounds, rasterScale);
|
||||
pdfShader = SkPDFShader::GetPDFShader(fDocument, shader, transform, bounds);
|
||||
|
||||
if (pdfShader.get()) {
|
||||
// pdfShader has been canonicalized so we can directly compare
|
||||
@ -2284,9 +2276,7 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
|
||||
|
||||
// Rasterize the bitmap using perspective in a new bitmap.
|
||||
if (origMatrix.hasPerspective()) {
|
||||
if (fRasterDpi == 0) {
|
||||
return;
|
||||
}
|
||||
SkASSERT(fDocument->rasterDpi() > 0);
|
||||
// Transform the bitmap in the new space, without taking into
|
||||
// account the initial transform.
|
||||
SkPath perspectiveOutline;
|
||||
@ -2302,8 +2292,8 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
|
||||
// account the initial transform.
|
||||
SkMatrix total = origMatrix;
|
||||
total.postConcat(fInitialTransform);
|
||||
SkScalar dpiScale = SkIntToScalar(fRasterDpi) /
|
||||
SkIntToScalar(DPI_FOR_RASTER_SCALE_ONE);
|
||||
SkScalar dpiScale = SkIntToScalar(fDocument->rasterDpi()) /
|
||||
SkIntToScalar(SkPDFUtils::kDpiForRasterScaleOne);
|
||||
total.postScale(dpiScale, dpiScale);
|
||||
|
||||
SkPath physicalPerspectiveOutline;
|
||||
|
@ -33,53 +33,42 @@ class SkPDFObject;
|
||||
class SkPDFStream;
|
||||
class SkRRect;
|
||||
|
||||
/** \class SkPDFDevice
|
||||
|
||||
The drawing context for the PDF backend.
|
||||
*/
|
||||
/**
|
||||
* \class SkPDFDevice
|
||||
*
|
||||
* An SkPDFDevice is the drawing context for a page or layer of PDF
|
||||
* content.
|
||||
*/
|
||||
class SkPDFDevice final : public SkClipStackDevice {
|
||||
public:
|
||||
/** Create a PDF drawing context. SkPDFDevice applies a
|
||||
* scale-and-translate transform to move the origin from the
|
||||
* bottom left (PDF default) to the top left (Skia default).
|
||||
/**
|
||||
* @param pageSize Page size in point units.
|
||||
* 1 point == 127/360 mm == 1/72 inch
|
||||
* @param rasterDpi the DPI at which features without native PDF
|
||||
* support will be rasterized (e.g. draw image with
|
||||
* perspective, draw text with perspective, ...). A
|
||||
* larger DPI would create a PDF that reflects the
|
||||
* original intent with better fidelity, but it can make
|
||||
* for larger PDF files too, which would use more memory
|
||||
* while rendering, and it would be slower to be processed
|
||||
* or sent online or to printer. A good choice is
|
||||
* SK_ScalarDefaultRasterDPI(72.0f).
|
||||
* @param SkPDFDocument. A non-null pointer back to the
|
||||
* document. The document is repsonsible for
|
||||
* @param document A non-null pointer back to the
|
||||
* PDFDocument object. The document is repsonsible for
|
||||
* de-duplicating across pages (via the SkPDFCanon) and
|
||||
* for early serializing of large immutable objects, such
|
||||
* as images (via SkPDFDocument::serialize()).
|
||||
*/
|
||||
static sk_sp<SkPDFDevice> Make(SkISize pageSize, SkScalar rasterDpi, SkPDFDocument* doc) {
|
||||
return sk_sp<SkPDFDevice>(new SkPDFDevice(pageSize, rasterDpi, doc, true));
|
||||
}
|
||||
SkPDFDevice(SkISize pageSize, SkPDFDocument* document);
|
||||
|
||||
/** Create a PDF drawing context without fipping the y-axis. */
|
||||
static sk_sp<SkPDFDevice> MakeUnflipped(SkISize pageSize,
|
||||
SkScalar rasterDpi,
|
||||
SkPDFDocument* doc) {
|
||||
return sk_sp<SkPDFDevice>(new SkPDFDevice(pageSize, rasterDpi, doc, false));
|
||||
}
|
||||
/**
|
||||
* Apply a scale-and-translate transform to move the origin from the
|
||||
* bottom left (PDF default) to the top left (Skia default).
|
||||
*/
|
||||
void setFlip();
|
||||
|
||||
sk_sp<SkPDFDevice> makeCongruentDevice() {
|
||||
return sk_sp<SkPDFDevice>(new SkPDFDevice(fPageSize, fRasterDpi, fDocument, false));
|
||||
return sk_make_sp<SkPDFDevice>(fPageSize, fDocument);
|
||||
}
|
||||
|
||||
~SkPDFDevice() override;
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
When these are called, we have already applied any saveLayer operations,
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
/**
|
||||
* These are called inside the per-device-layer loop for each draw call.
|
||||
* When these are called, we have already applied any saveLayer
|
||||
* operations, and are handling any looping from the paint, and any
|
||||
* effects from the DrawFilter.
|
||||
*/
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode,
|
||||
@ -212,15 +201,9 @@ private:
|
||||
};
|
||||
SkSinglyLinkedList<ContentEntry> fContentEntries;
|
||||
|
||||
SkScalar fRasterDpi;
|
||||
|
||||
SkPDFDocument* fDocument;
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkPDFDevice(SkISize pageSize,
|
||||
SkScalar rasterDpi,
|
||||
SkPDFDocument* doc,
|
||||
bool flip);
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
|
||||
|
||||
|
@ -215,7 +215,8 @@ SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height,
|
||||
}
|
||||
SkISize pageSize = SkISize::Make(
|
||||
SkScalarRoundToInt(width), SkScalarRoundToInt(height));
|
||||
fPageDevice = SkPDFDevice::Make(pageSize, fRasterDpi, this);
|
||||
fPageDevice = sk_make_sp<SkPDFDevice>(pageSize, this);
|
||||
fPageDevice->setFlip(); // Only the top-level device needs to be flipped.
|
||||
fCanvas.reset(new SkPDFCanvas(fPageDevice));
|
||||
if (SkRect::MakeWH(width, height) != trimBox) {
|
||||
fCanvas->clipRect(trimBox);
|
||||
@ -439,6 +440,9 @@ sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream,
|
||||
const SkDocument::PDFMetadata& metadata,
|
||||
sk_sp<SkPixelSerializer> jpeg,
|
||||
bool pdfa) {
|
||||
if (dpi <= 0) {
|
||||
dpi = 72.0f;
|
||||
}
|
||||
return stream ? sk_make_sp<SkPDFDocument>(stream, proc, dpi, metadata,
|
||||
std::move(jpeg), pdfa)
|
||||
: nullptr;
|
||||
|
@ -14,6 +14,16 @@
|
||||
|
||||
class SkPDFDevice;
|
||||
|
||||
/* @param rasterDpi the DPI at which features without native PDF
|
||||
* support will be rasterized (e.g. draw image with
|
||||
* perspective, draw text with perspective, ...). A
|
||||
* larger DPI would create a PDF that reflects the
|
||||
* original intent with better fidelity, but it can make
|
||||
* for larger PDF files too, which would use more memory
|
||||
* while rendering, and it would be slower to be processed
|
||||
* or sent online or to printer. A good choice is
|
||||
* SK_ScalarDefaultRasterDPI(72.0f).
|
||||
*/
|
||||
sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream,
|
||||
void (*doneProc)(SkWStream*, bool),
|
||||
SkScalar rasterDpi,
|
||||
@ -67,6 +77,7 @@ public:
|
||||
*/
|
||||
void serialize(const sk_sp<SkPDFObject>&);
|
||||
SkPDFCanon* canon() { return &fCanon; }
|
||||
SkScalar rasterDpi() const { return fRasterDpi; }
|
||||
void registerFont(SkPDFFont* f) { fFonts.add(f); }
|
||||
|
||||
private:
|
||||
|
@ -275,7 +275,7 @@ static sk_sp<SkPDFDict> gradientStitchCode(const SkShader::GradientInfo& info) {
|
||||
|
||||
encode->appendScalar(0);
|
||||
encode->appendScalar(1.0f);
|
||||
|
||||
|
||||
functions->appendObject(createInterpolationFunction(colorData[i-1], colorData[i]));
|
||||
}
|
||||
|
||||
@ -525,19 +525,16 @@ static void drawBitmapMatrix(SkCanvas* canvas, const SkBitmap& bm, const SkMatri
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
const SkPDFShader::State& state);
|
||||
static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
|
||||
const SkPDFShader::State& state);
|
||||
|
||||
static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
const SkPDFShader::State& state,
|
||||
SkBitmap image);
|
||||
|
||||
static sk_sp<SkPDFObject> get_pdf_shader_by_state(
|
||||
SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
SkPDFShader::State state,
|
||||
SkBitmap image) {
|
||||
SkPDFCanon* canon = doc->canon();
|
||||
@ -550,14 +547,14 @@ static sk_sp<SkPDFObject> get_pdf_shader_by_state(
|
||||
} else if (state.fType == SkShader::kNone_GradientType) {
|
||||
sk_sp<SkPDFObject> shader = canon->findImageShader(state);
|
||||
if (!shader) {
|
||||
shader = make_image_shader(doc, dpi, state, std::move(image));
|
||||
shader = make_image_shader(doc, state, std::move(image));
|
||||
canon->addImageShader(shader, std::move(state));
|
||||
}
|
||||
return shader;
|
||||
} else if (state.GradientHasAlpha()) {
|
||||
sk_sp<SkPDFObject> shader = canon->findAlphaShader(state);
|
||||
if (!shader) {
|
||||
shader = make_alpha_function_shader(doc, dpi, state);
|
||||
shader = make_alpha_function_shader(doc, state);
|
||||
canon->addAlphaShader(shader, std::move(state));
|
||||
}
|
||||
return shader;
|
||||
@ -572,18 +569,17 @@ static sk_sp<SkPDFObject> get_pdf_shader_by_state(
|
||||
}
|
||||
|
||||
sk_sp<SkPDFObject> SkPDFShader::GetPDFShader(SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
SkShader* shader,
|
||||
const SkMatrix& matrix,
|
||||
const SkIRect& surfaceBBox,
|
||||
SkScalar rasterScale) {
|
||||
const SkIRect& surfaceBBox) {
|
||||
if (surfaceBBox.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
SkScalar rasterDpi = doc->rasterDpi();
|
||||
SkScalar rasterScale = SkIntToScalar(rasterDpi) / SkPDFUtils::kDpiForRasterScaleOne;
|
||||
SkBitmap image;
|
||||
State state(shader, matrix, surfaceBBox, rasterScale, &image);
|
||||
return get_pdf_shader_by_state(
|
||||
doc, dpi, std::move(state), std::move(image));
|
||||
return get_pdf_shader_by_state(doc, std::move(state), std::move(image));
|
||||
}
|
||||
|
||||
static sk_sp<SkPDFDict> get_gradient_resource_dict(
|
||||
@ -644,14 +640,13 @@ static std::unique_ptr<SkStreamAsset> create_pattern_fill_content(
|
||||
* Creates a ExtGState with the SMask set to the luminosityShader in
|
||||
* luminosity mode. The shader pattern extends to the bbox.
|
||||
*/
|
||||
static sk_sp<SkPDFObject> create_smask_graphic_state(
|
||||
SkPDFDocument* doc, SkScalar dpi, const SkPDFShader::State& state) {
|
||||
static sk_sp<SkPDFObject> create_smask_graphic_state(SkPDFDocument* doc,
|
||||
const SkPDFShader::State& state) {
|
||||
SkRect bbox;
|
||||
bbox.set(state.fBBox);
|
||||
|
||||
sk_sp<SkPDFObject> luminosityShader(
|
||||
get_pdf_shader_by_state(doc, dpi, state.MakeAlphaToLuminosityState(),
|
||||
SkBitmap()));
|
||||
get_pdf_shader_by_state(doc, state.MakeAlphaToLuminosityState(), SkBitmap()));
|
||||
|
||||
std::unique_ptr<SkStreamAsset> alphaStream(create_pattern_fill_content(-1, bbox));
|
||||
|
||||
@ -670,7 +665,6 @@ static sk_sp<SkPDFObject> create_smask_graphic_state(
|
||||
}
|
||||
|
||||
static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
const SkPDFShader::State& state) {
|
||||
SkRect bbox;
|
||||
bbox.set(state.fBBox);
|
||||
@ -678,14 +672,14 @@ static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
|
||||
SkPDFShader::State opaqueState(state.MakeOpaqueState());
|
||||
|
||||
sk_sp<SkPDFObject> colorShader(
|
||||
get_pdf_shader_by_state(doc, dpi, std::move(opaqueState), SkBitmap()));
|
||||
get_pdf_shader_by_state(doc, std::move(opaqueState), SkBitmap()));
|
||||
if (!colorShader) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create resource dict with alpha graphics state as G0 and
|
||||
// pattern shader as P0, then write content stream.
|
||||
sk_sp<SkPDFObject> alphaGs = create_smask_graphic_state(doc, dpi, state);
|
||||
sk_sp<SkPDFObject> alphaGs = create_smask_graphic_state(doc, state);
|
||||
|
||||
sk_sp<SkPDFDict> resourceDict =
|
||||
get_gradient_resource_dict(colorShader.get(), alphaGs.get());
|
||||
@ -695,7 +689,7 @@ static sk_sp<SkPDFStream> make_alpha_function_shader(SkPDFDocument* doc,
|
||||
auto alphaFunctionShader = sk_make_sp<SkPDFStream>(std::move(colorStream));
|
||||
|
||||
populate_tiling_pattern_dict(alphaFunctionShader->dict(), bbox,
|
||||
std::move(resourceDict), SkMatrix::I());
|
||||
std::move(resourceDict), SkMatrix::I());
|
||||
return alphaFunctionShader;
|
||||
}
|
||||
|
||||
@ -912,9 +906,9 @@ static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
|
||||
domain->appendScalar(bbox.fRight);
|
||||
domain->appendScalar(bbox.fTop);
|
||||
domain->appendScalar(bbox.fBottom);
|
||||
|
||||
|
||||
SkDynamicMemoryWStream functionCode;
|
||||
|
||||
|
||||
if (state.fType == SkShader::kConical_GradientType) {
|
||||
SkShader::GradientInfo twoPointRadialInfo = *info;
|
||||
SkMatrix inverseMapperMatrix;
|
||||
@ -930,7 +924,7 @@ static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
|
||||
} else {
|
||||
codeFunction(*info, perspectiveInverseOnly, &functionCode);
|
||||
}
|
||||
|
||||
|
||||
pdfShader->insertObject("Domain", domain);
|
||||
|
||||
std::unique_ptr<SkStreamAsset> functionStream(functionCode.detachAsStream());
|
||||
@ -957,7 +951,6 @@ static sk_sp<SkPDFDict> make_function_shader(SkPDFCanon* canon,
|
||||
}
|
||||
|
||||
static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
const SkPDFShader::State& state,
|
||||
SkBitmap image) {
|
||||
SkASSERT(state.fBitmapKey ==
|
||||
@ -994,7 +987,7 @@ static sk_sp<SkPDFStream> make_image_shader(SkPDFDocument* doc,
|
||||
|
||||
SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()),
|
||||
SkScalarRoundToInt(deviceBounds.height()));
|
||||
sk_sp<SkPDFDevice> patternDevice = SkPDFDevice::MakeUnflipped(size, dpi, doc);
|
||||
auto patternDevice = sk_make_sp<SkPDFDevice>(size, doc);
|
||||
SkCanvas canvas(patternDevice.get());
|
||||
|
||||
SkRect patternBBox;
|
||||
|
@ -37,15 +37,11 @@ public:
|
||||
* positioned, relative to where the page is drawn.)
|
||||
* @param surfceBBox The bounding box of the drawing surface (with matrix
|
||||
* already applied).
|
||||
* @param rasterScale Additional scale to be applied for early
|
||||
* rasterization.
|
||||
*/
|
||||
static sk_sp<SkPDFObject> GetPDFShader(SkPDFDocument* doc,
|
||||
SkScalar dpi,
|
||||
SkShader* shader,
|
||||
const SkMatrix& matrix,
|
||||
const SkIRect& surfaceBBox,
|
||||
SkScalar rasterScale);
|
||||
const SkIRect& surfaceBBox);
|
||||
|
||||
static sk_sp<SkPDFArray> MakeRangeObject();
|
||||
|
||||
|
@ -35,6 +35,8 @@ struct SkRect;
|
||||
|
||||
namespace SkPDFUtils {
|
||||
|
||||
constexpr float kDpiForRasterScaleOne = 72.0f;
|
||||
|
||||
sk_sp<SkPDFArray> RectToArray(const SkRect& rect);
|
||||
sk_sp<SkPDFArray> MatrixToArray(const SkMatrix& matrix);
|
||||
void AppendTransform(const SkMatrix& matrix, SkWStream* content);
|
||||
|
Loading…
Reference in New Issue
Block a user