180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkData.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkGeometry.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPaint.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPath.h" 1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkPDFResourceDict.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPDFUtils.h" 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h" 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h" 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPDFTypes.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger//static 2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkPDFArray* SkPDFUtils::RectToArray(const SkRect& rect) { 2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkPDFArray* result = new SkPDFArray(); 2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger result->reserve(4); 2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger result->appendScalar(rect.fLeft); 2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger result->appendScalar(rect.fTop); 2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger result->appendScalar(rect.fRight); 2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger result->appendScalar(rect.fBottom); 2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return result; 2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPDFArray* SkPDFUtils::MatrixToArray(const SkMatrix& matrix) { 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar values[6]; 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!matrix.asAffine(values)) { 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::SetAffineIdentity(values); 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFArray* result = new SkPDFArray; 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result->reserve(6); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) { 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result->appendScalar(values[i]); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return result; 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::AppendTransform(const SkMatrix& matrix, SkWStream* content) { 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar values[6]; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!matrix.asAffine(values)) { 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::SetAffineIdentity(values); 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) { 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(values[i], content); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("cm\n"); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkWStream* content) { 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(x, content); 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(y, content); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" m\n"); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkWStream* content) { 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(x, content); 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(y, content); 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" l\n"); 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::AppendCubic(SkScalar ctl1X, SkScalar ctl1Y, 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ctl2X, SkScalar ctl2Y, 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar dstX, SkScalar dstY, SkWStream* content) { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString cmd("y\n"); 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(ctl1X, content); 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(ctl1Y, content); 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (ctl2X != dstX || ctl2Y != dstY) { 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru cmd.set("c\n"); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(ctl2X, content); 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(ctl2Y, content); 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(dstX, content); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(dstY, content); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(cmd.c_str()); 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::AppendRectangle(const SkRect& rect, SkWStream* content) { 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Skia has 0,0 at top left, pdf at bottom left. Do the right thing. 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar bottom = SkMinScalar(rect.fBottom, rect.fTop); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(rect.fLeft, content); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(bottom, content); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(rect.width(), content); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" "); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFScalar::Append(rect.height(), content); 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" re\n"); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle, 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkWStream* content) { 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Filling a path with no area results in a drawing in PDF renderers but 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Chrome expects to be able to draw some such entities with no visible 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // result, so we detect those cases and discard the drawing for them. 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Specifically: moveTo(X), lineTo(Y) and moveTo(X), lineTo(X), lineTo(Y). 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum SkipFillState { 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kEmpty_SkipFillState = 0, 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kSingleLine_SkipFillState = 1, 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kNonSingleLine_SkipFillState = 2, 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkipFillState fillState = kEmpty_SkipFillState; 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paintStyle != SkPaint::kFill_Style) { 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState = kNonSingleLine_SkipFillState; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkPoint lastMovePt = SkPoint::Make(0,0); 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDynamicMemoryWStream currentSegment; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint args[4]; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPath::Iter iter(path, false); 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (SkPath::Verb verb = iter.next(args); 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verb != SkPath::kDone_Verb; 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verb = iter.next(args)) { 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // args gets all the points, even the implicit first point. 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (verb) { 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkPath::kMove_Verb: 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru MoveTo(args[0].fX, args[0].fY, ¤tSegment); 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru lastMovePt = args[0]; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState = kEmpty_SkipFillState; 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkPath::kLine_Verb: 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AppendLine(args[1].fX, args[1].fY, ¤tSegment); 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fillState == kEmpty_SkipFillState) { 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (args[0] != lastMovePt) { 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState = kSingleLine_SkipFillState; 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (fillState == kSingleLine_SkipFillState) { 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState = kNonSingleLine_SkipFillState; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkPath::kQuad_Verb: { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint cubic[4]; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertQuadToCubic(args, cubic); 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AppendCubic(cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY, 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru cubic[3].fX, cubic[3].fY, ¤tSegment); 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState = kNonSingleLine_SkipFillState; 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkPath::kCubic_Verb: 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AppendCubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY, 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru args[3].fX, args[3].fY, ¤tSegment); 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fillState = kNonSingleLine_SkipFillState; 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkPath::kClose_Verb: 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fillState != kSingleLine_SkipFillState) { 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ClosePath(¤tSegment); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkData* data = currentSegment.copyToData(); 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->write(data->data(), data->size()); 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data->unref(); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru currentSegment.reset(); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(false); 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (currentSegment.bytesWritten() > 0) { 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkData* data = currentSegment.copyToData(); 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->write(data->data(), data->size()); 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru data->unref(); 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::ClosePath(SkWStream* content) { 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("h\n"); 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::PaintPath(SkPaint::Style style, SkPath::FillType fill, 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkWStream* content) { 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (style == SkPaint::kFill_Style) { 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("f"); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (style == SkPaint::kStrokeAndFill_Style) { 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("B"); 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (style == SkPaint::kStroke_Style) { 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("S"); 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (style != SkPaint::kStroke_Style) { 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NOT_IMPLEMENTED(fill == SkPath::kInverseEvenOdd_FillType, false); 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NOT_IMPLEMENTED(fill == SkPath::kInverseWinding_FillType, false); 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fill == SkPath::kEvenOdd_FillType) { 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("*"); 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText("\n"); 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::StrokePath(SkWStream* content) { 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPDFUtils::PaintPath( 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPaint::kStroke_Style, SkPath::kWinding_FillType, content); 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::DrawFormXObject(int objectIndex, SkWStream* content) { 22158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText("/"); 22258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText(SkPDFResourceDict::getResourceName( 22358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkPDFResourceDict::kXObject_ResourceType, 22458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger objectIndex).c_str()); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" Do\n"); 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// static 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFUtils::ApplyGraphicState(int objectIndex, SkWStream* content) { 23058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText("/"); 23158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText(SkPDFResourceDict::getResourceName( 23258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkPDFResourceDict::kExtGState_ResourceType, 23358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger objectIndex).c_str()); 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru content->writeText(" gs\n"); 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 23758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// static 23858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid SkPDFUtils::ApplyPattern(int objectIndex, SkWStream* content) { 23958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Select Pattern color space (CS, cs) and set pattern object as current 24058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // color (SCN, scn) 24158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkString resourceName = SkPDFResourceDict::getResourceName( 24258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkPDFResourceDict::kPattern_ResourceType, 24358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger objectIndex); 24458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText("/Pattern CS/Pattern cs/"); 24558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText(resourceName.c_str()); 24658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText(" SCN/"); 24758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText(resourceName.c_str()); 24858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger content->writeText(" scn\n"); 24958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 250