chromium/third_party/skia/src/pdf/SkPDFDevice.cpp

/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/pdf/SkPDFDevice.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkM44.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/docs/SkPDFDocument.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkScopeExit.h"
#include "src/base/SkTLazy.h"
#include "src/base/SkUTF.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkAnnotationKeys.h"
#include "src/core/SkBitmapDevice.h"
#include "src/core/SkBlendModePriv.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkDevice.h"
#include "src/core/SkDraw.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMask.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkStrikeSpec.h"
#include "src/pdf/SkBitmapKey.h"
#include "src/pdf/SkClusterator.h"
#include "src/pdf/SkPDFBitmap.h"
#include "src/pdf/SkPDFDocumentPriv.h"
#include "src/pdf/SkPDFFont.h"
#include "src/pdf/SkPDFFormXObject.h"
#include "src/pdf/SkPDFGraphicState.h"
#include "src/pdf/SkPDFResourceDict.h"
#include "src/pdf/SkPDFShader.h"
#include "src/pdf/SkPDFTag.h"
#include "src/pdf/SkPDFTypes.h"
#include "src/pdf/SkPDFUtils.h"
#include "src/shaders/SkColorShader.h"
#include "src/shaders/SkShaderBase.h"
#include "src/text/GlyphRun.h"
#include "src/utils/SkClipStackUtils.h"

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <utility>
#include <vector>

class SkBlender;
class SkMesh;
class SkVertices;

usingnamespaceskia_private;

#ifndef SK_PDF_MASK_QUALITY
    // If MASK_QUALITY is in [0,100], will be used for JpegEncoder.
    // Otherwise, just encode masks losslessly.
    #define SK_PDF_MASK_QUALITY
    // Since these masks are used for blurry shadows, we shouldn't need
    // high quality.  Raise this value if your shadows have visible JPEG
    // artifacts.
    // If SkJpegEncoder::Encode fails, we will fall back to the lossless
    // encoding.
#endif

namespace {

// If nodeId is not zero, outputs the tags to begin a marked-content sequence
// for the given node ID, and then closes those tags when this object goes
// out of scope.
class ScopedOutputMarkedContentTags {};

}  // namespace

// Utility functions

// This function destroys the mask and either frees or takes the pixels.
sk_sp<SkImage> mask_to_greyscale_image(SkMaskBuilder* mask) {}

sk_sp<SkImage> alpha_image_to_greyscale_image(const SkImage* mask) {}

static int add_resource(THashSet<SkPDFIndirectReference>& resources, SkPDFIndirectReference ref) {}

static void draw_points(SkCanvas::PointMode mode,
                        size_t count,
                        const SkPoint* points,
                        const SkPaint& paint,
                        const SkIRect& bounds,
                        SkDevice* device) {}

static void transform_shader(SkPaint* paint, const SkMatrix& ctm) {}


static SkTCopyOnFirstWrite<SkPaint> clean_paint(const SkPaint& srcPaint) {}

static void set_style(SkTCopyOnFirstWrite<SkPaint>* paint, SkPaint::Style style) {}

/* Calculate an inverted path's equivalent non-inverted path, given the
 * canvas bounds.
 * outPath may alias with invPath (since this is supported by PathOps).
 */
static bool calculate_inverse_path(const SkRect& bounds, const SkPath& invPath,
                                   SkPath* outPath) {}

sk_sp<SkDevice> SkPDFDevice::createDevice(const CreateInfo& cinfo, const SkPaint* layerPaint) {}

// 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 {};

////////////////////////////////////////////////////////////////////////////////

SkPDFDevice::SkPDFDevice(SkISize pageSize, SkPDFDocument* doc, const SkMatrix& transform)
        :{}

SkPDFDevice::~SkPDFDevice() = default;

void SkPDFDevice::reset() {}

void SkPDFDevice::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {}

void SkPDFDevice::drawPaint(const SkPaint& srcPaint) {}

void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
                             size_t count,
                             const SkPoint* points,
                             const SkPaint& srcPaint) {}

void SkPDFDevice::drawRect(const SkRect& rect, const SkPaint& paint) {}

void SkPDFDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {}

void SkPDFDevice::drawOval(const SkRect& oval, const SkPaint& paint) {}

void SkPDFDevice::drawPath(const SkPath& path, const SkPaint& paint, bool pathIsMutable) {}

void SkPDFDevice::internalDrawPathWithFilter(const SkClipStack& clipStack,
                                             const SkMatrix& ctm,
                                             const SkPath& origPath,
                                             const SkPaint& origPaint) {}

void SkPDFDevice::setGraphicState(SkPDFIndirectReference gs, SkDynamicMemoryWStream* content) {}

void SkPDFDevice::clearMaskOnGraphicState(SkDynamicMemoryWStream* contentStream) {}

void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
                                   const SkMatrix& ctm,
                                   const SkPath& origPath,
                                   const SkPaint& srcPaint,
                                   bool pathIsMutable) {}

////////////////////////////////////////////////////////////////////////////////

void SkPDFDevice::drawImageRect(const SkImage* image,
                                const SkRect* src,
                                const SkRect& dst,
                                const SkSamplingOptions& sampling,
                                const SkPaint& paint,
                                SkCanvas::SrcRectConstraint) {}

void SkPDFDevice::drawSprite(const SkBitmap& bm, int x, int y, const SkPaint& paint) {}

////////////////////////////////////////////////////////////////////////////////

namespace {
class GlyphPositioner {};
}  // namespace

static SkUnichar map_glyph(const std::vector<SkUnichar>& glyphToUnicode, SkGlyphID glyph) {}

namespace {
struct PositionedGlyph {};
}  // namespace

static SkRect get_glyph_bounds_device_space(const SkGlyph* glyph,
                                            SkScalar xScale, SkScalar yScale,
                                            SkPoint xy, const SkMatrix& ctm) {}

static bool contains(const SkRect& r, SkPoint p) {}

void SkPDFDevice::drawGlyphRunAsPath(
        const sktext::GlyphRun& glyphRun, SkPoint offset, const SkPaint& runPaint) {}

static bool needs_new_font(SkPDFFont* font, const SkGlyph* glyph,
                           SkAdvancedTypefaceMetrics::FontType fontType) {}

void SkPDFDevice::internalDrawGlyphRun(
        const sktext::GlyphRun& glyphRun, SkPoint offset, const SkPaint& runPaint) {}

void SkPDFDevice::onDrawGlyphRunList(SkCanvas*,
                                     const sktext::GlyphRunList& glyphRunList,
                                     const SkPaint& paint) {}

void SkPDFDevice::drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) {}

void SkPDFDevice::drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) {}

void SkPDFDevice::drawFormXObject(SkPDFIndirectReference xObject, SkDynamicMemoryWStream* content,
                                  SkPath* shape) {}

sk_sp<SkSurface> SkPDFDevice::makeSurface(const SkImageInfo& info, const SkSurfaceProps& props) {}

static std::vector<SkPDFIndirectReference> sort(const THashSet<SkPDFIndirectReference>& src) {}

std::unique_ptr<SkPDFDict> SkPDFDevice::makeResourceDict() {}

std::unique_ptr<SkStreamAsset> SkPDFDevice::content() {}

/* Draws an inverse filled path by using Path Ops to compute the positive
 * inverse using the current clip as the inverse bounds.
 * Return true if this was an inverse path and was properly handled,
 * otherwise returns false and the normal drawing routine should continue,
 * either as a (incorrect) fallback or because the path was not inverse
 * in the first place.
 */
bool SkPDFDevice::handleInversePath(const SkPath& origPath,
                                    const SkPaint& paint,
                                    bool pathIsMutable) {}

SkPDFIndirectReference SkPDFDevice::makeFormXObjectFromDevice(SkIRect bounds, bool alpha) {}

SkPDFIndirectReference SkPDFDevice::makeFormXObjectFromDevice(bool alpha) {}

void SkPDFDevice::drawFormXObjectWithMask(SkPDFIndirectReference xObject,
                                          SkPDFIndirectReference sMask,
                                          SkBlendMode mode,
                                          bool invertClip) {}


static bool treat_as_regular_pdf_blend_mode(SkBlendMode blendMode) {}

static void populate_graphic_state_entry_from_paint(
        SkPDFDocument* doc,
        const SkMatrix& matrix,
        const SkClipStack* clipStack,
        SkIRect deviceBounds,
        const SkPaint& paint,
        const SkMatrix& initialTransform,
        SkScalar textScale,
        SkPDFGraphicStackState::Entry* entry,
        THashSet<SkPDFIndirectReference>* shaderResources,
        THashSet<SkPDFIndirectReference>* graphicStateResources) {}

SkDynamicMemoryWStream* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack,
                                                       const SkMatrix& matrix,
                                                       const SkPaint& paint,
                                                       SkScalar textScale,
                                                       SkPDFIndirectReference* dst) {}

void SkPDFDevice::finishContentEntry(const SkClipStack* clipStack,
                                     SkBlendMode blendMode,
                                     SkPDFIndirectReference dst,
                                     SkPath* shape) {}

bool SkPDFDevice::isContentEmpty() {}

static SkSize rect_to_size(const SkRect& r) {}

static sk_sp<SkImage> color_filter(const SkImage* image,
                                   SkColorFilter* colorFilter) {}

////////////////////////////////////////////////////////////////////////////////

static bool is_integer(SkScalar x) {}

static bool is_integral(const SkRect& r) {}

void SkPDFDevice::internalDrawImageRect(SkKeyedImage imageSubset,
                                        const SkRect* src,
                                        const SkRect& dst,
                                        const SkSamplingOptions& sampling,
                                        const SkPaint& srcPaint,
                                        const SkMatrix& ctm) {}

///////////////////////////////////////////////////////////////////////////////////////////////////


void SkPDFDevice::drawDevice(SkDevice* device, const SkSamplingOptions& sampling,
                             const SkPaint& paint) {}

void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, const SkMatrix& localToDevice,
                              const SkSamplingOptions& sampling, const SkPaint& paint,
                              SkCanvas::SrcRectConstraint) {}

sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkBitmap& bitmap) {}

sk_sp<SkSpecialImage> SkPDFDevice::makeSpecial(const SkImage* image) {}