1685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
2066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org/*
3685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2011 Google Inc.
4066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org *
5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file.
7066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org */
8066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
9685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com
10af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org#include "SkData.h"
11fa2c6802e2e827a1afb7a263895ef2a9727fbde1reed@google.com#include "SkGeometry.h"
12066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org#include "SkPaint.h"
13066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org#include "SkPath.h"
1492f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org#include "SkPDFResourceDict.h"
15066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org#include "SkPDFUtils.h"
16e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org#include "SkStream.h"
17066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org#include "SkString.h"
18066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org#include "SkPDFTypes.h"
19066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
209d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org//static
219d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.orgSkPDFArray* SkPDFUtils::RectToArray(const SkRect& rect) {
229d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    SkPDFArray* result = new SkPDFArray();
239d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    result->reserve(4);
249d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    result->appendScalar(rect.fLeft);
259d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    result->appendScalar(rect.fTop);
269d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    result->appendScalar(rect.fRight);
279d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    result->appendScalar(rect.fBottom);
289d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    return result;
299d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org}
309d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org
31066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
32066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.orgSkPDFArray* SkPDFUtils::MatrixToArray(const SkMatrix& matrix) {
33066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkScalar values[6];
34001f87e4548c48f083e652735a4703d40eb4ad6fbungeman@google.com    if (!matrix.asAffine(values)) {
35001f87e4548c48f083e652735a4703d40eb4ad6fbungeman@google.com        SkMatrix::SetAffineIdentity(values);
36001f87e4548c48f083e652735a4703d40eb4ad6fbungeman@google.com    }
37066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
38066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFArray* result = new SkPDFArray;
39066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    result->reserve(6);
40066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) {
414a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com        result->appendScalar(values[i]);
42066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    }
43066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    return result;
44066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
45066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
46066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
479d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.orgvoid SkPDFUtils::AppendTransform(const SkMatrix& matrix, SkWStream* content) {
489d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org    SkScalar values[6];
49001f87e4548c48f083e652735a4703d40eb4ad6fbungeman@google.com    if (!matrix.asAffine(values)) {
50001f87e4548c48f083e652735a4703d40eb4ad6fbungeman@google.com        SkMatrix::SetAffineIdentity(values);
51001f87e4548c48f083e652735a4703d40eb4ad6fbungeman@google.com    }
529d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) {
539d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org        SkPDFScalar::Append(values[i], content);
549d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org        content->writeText(" ");
559d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org    }
569d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org    content->writeText("cm\n");
579d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org}
589d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org
599d58a392f6c084ea764fbe7cded2591987c427f2vandebo@chromium.org// static
60e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.orgvoid SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkWStream* content) {
61066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(x, content);
62e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
63066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(y, content);
64e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" m\n");
65066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
66066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
67066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
68e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.orgvoid SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkWStream* content) {
69066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(x, content);
70e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
71066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(y, content);
72e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" l\n");
73066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
74066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
75066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
76066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.orgvoid SkPDFUtils::AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
77066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                             SkScalar ctl2X, SkScalar ctl2Y,
78e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org                             SkScalar dstX, SkScalar dstY, SkWStream* content) {
79066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkString cmd("y\n");
80066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(ctl1X, content);
81e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
82066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(ctl1Y, content);
83e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
84066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    if (ctl2X != dstX || ctl2Y != dstY) {
85066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        cmd.set("c\n");
86066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        SkPDFScalar::Append(ctl2X, content);
87e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org        content->writeText(" ");
88066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        SkPDFScalar::Append(ctl2Y, content);
89e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org        content->writeText(" ");
90066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    }
91066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(dstX, content);
92e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
93066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFScalar::Append(dstY, content);
94e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
95e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(cmd.c_str());
96066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
97066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
98066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
99af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.orgvoid SkPDFUtils::AppendRectangle(const SkRect& rect, SkWStream* content) {
100af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org    // Skia has 0,0 at top left, pdf at bottom left.  Do the right thing.
101af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org    SkScalar bottom = SkMinScalar(rect.fBottom, rect.fTop);
102af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org
103af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org    SkPDFScalar::Append(rect.fLeft, content);
104e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
105af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org    SkPDFScalar::Append(bottom, content);
106e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
107af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org    SkPDFScalar::Append(rect.width(), content);
108e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" ");
109af12345812274bf783ba9a7ce4d5bcf72cebfa96vandebo@chromium.org    SkPDFScalar::Append(rect.height(), content);
110e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText(" re\n");
111066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
112066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
113e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org// static
114af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.orgvoid SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
115af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                          SkWStream* content) {
116af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    // Filling a path with no area results in a drawing in PDF renderers but
117af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    // Chrome expects to be able to draw some such entities with no visible
118af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    // result, so we detect those cases and discard the drawing for them.
119af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    // Specifically: moveTo(X), lineTo(Y) and moveTo(X), lineTo(X), lineTo(Y).
120af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    enum SkipFillState {
121af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        kEmpty_SkipFillState         = 0,
122af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        kSingleLine_SkipFillState    = 1,
123af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        kNonSingleLine_SkipFillState = 2,
124af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    };
125af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    SkipFillState fillState = kEmpty_SkipFillState;
126af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    if (paintStyle != SkPaint::kFill_Style) {
127af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        fillState = kNonSingleLine_SkipFillState;
128af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    }
129d9ad864e9acb917fe0539cbdc067c859ae6090d9sugoi@google.com    SkPoint lastMovePt = SkPoint::Make(0,0);
130af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    SkDynamicMemoryWStream currentSegment;
131066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPoint args[4];
132066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPath::Iter iter(path, false);
133066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    for (SkPath::Verb verb = iter.next(args);
134066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org         verb != SkPath::kDone_Verb;
135066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org         verb = iter.next(args)) {
136066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        // args gets all the points, even the implicit first point.
137066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        switch (verb) {
138066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            case SkPath::kMove_Verb:
139af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                MoveTo(args[0].fX, args[0].fY, &currentSegment);
140af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                lastMovePt = args[0];
141af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                fillState = kEmpty_SkipFillState;
142066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                break;
143066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            case SkPath::kLine_Verb:
144af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                AppendLine(args[1].fX, args[1].fY, &currentSegment);
145af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                if (fillState == kEmpty_SkipFillState) {
146af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                   if (args[0] != lastMovePt) {
147af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                       fillState = kSingleLine_SkipFillState;
148af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                   }
149af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                } else if (fillState == kSingleLine_SkipFillState) {
150af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                    fillState = kNonSingleLine_SkipFillState;
151af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                }
152066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                break;
153066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            case SkPath::kQuad_Verb: {
154fa2c6802e2e827a1afb7a263895ef2a9727fbde1reed@google.com                SkPoint cubic[4];
155fa2c6802e2e827a1afb7a263895ef2a9727fbde1reed@google.com                SkConvertQuadToCubic(args, cubic);
156fa2c6802e2e827a1afb7a263895ef2a9727fbde1reed@google.com                AppendCubic(cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY,
157af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                            cubic[3].fX, cubic[3].fY, &currentSegment);
158af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                fillState = kNonSingleLine_SkipFillState;
159066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                break;
160066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            }
161066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            case SkPath::kCubic_Verb:
162066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                AppendCubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY,
163af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                            args[3].fX, args[3].fY, &currentSegment);
164af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                fillState = kNonSingleLine_SkipFillState;
165066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                break;
166066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            case SkPath::kClose_Verb:
167af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                if (fillState != kSingleLine_SkipFillState) {
168af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                    ClosePath(&currentSegment);
169af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                    SkData* data = currentSegment.copyToData();
170af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                    content->write(data->data(), data->size());
171af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                    data->unref();
172af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                }
173af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org                currentSegment.reset();
174066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                break;
175066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org            default:
176066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                SkASSERT(false);
177066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org                break;
178066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        }
179066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    }
180af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    if (currentSegment.bytesWritten() > 0) {
181af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        SkData* data = currentSegment.copyToData();
182af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        content->write(data->data(), data->size());
183af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org        data->unref();
184af54f4c68afab91f9871bcf78be070532093e3f0vandebo@chromium.org    }
185066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
186066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
187066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
188e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.orgvoid SkPDFUtils::ClosePath(SkWStream* content) {
189e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText("h\n");
190066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
191066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
192066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
193066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.orgvoid SkPDFUtils::PaintPath(SkPaint::Style style, SkPath::FillType fill,
194e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org                           SkWStream* content) {
195c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    if (style == SkPaint::kFill_Style) {
196e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org        content->writeText("f");
197c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    } else if (style == SkPaint::kStrokeAndFill_Style) {
198e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org        content->writeText("B");
199c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    } else if (style == SkPaint::kStroke_Style) {
200e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org        content->writeText("S");
201c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org    }
202066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
203066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    if (style != SkPaint::kStroke_Style) {
204066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        NOT_IMPLEMENTED(fill == SkPath::kInverseEvenOdd_FillType, false);
205066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        NOT_IMPLEMENTED(fill == SkPath::kInverseWinding_FillType, false);
206c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org        if (fill == SkPath::kEvenOdd_FillType) {
207e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org            content->writeText("*");
208c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org        }
209066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    }
210e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.org    content->writeText("\n");
211066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
212066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org
213066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org// static
214e026476bc10a5c010fc8388c4a54eaab2b9111b1vandebo@chromium.orgvoid SkPDFUtils::StrokePath(SkWStream* content) {
215066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org    SkPDFUtils::PaintPath(
216066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org        SkPaint::kStroke_Style, SkPath::kWinding_FillType, content);
217066ee8bc8b6f368ff85ee5d3f0b6ed1639610566ctguil@chromium.org}
218e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org
219e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org// static
220e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.orgvoid SkPDFUtils::DrawFormXObject(int objectIndex, SkWStream* content) {
22192f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org    content->writeText("/");
22292f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org    content->writeText(SkPDFResourceDict::getResourceName(
22392f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org            SkPDFResourceDict::kXObject_ResourceType,
22492f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org            objectIndex).c_str());
225e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org    content->writeText(" Do\n");
226e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org}
227e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org
228e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org// static
229e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.orgvoid SkPDFUtils::ApplyGraphicState(int objectIndex, SkWStream* content) {
23092f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org    content->writeText("/");
23192f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org    content->writeText(SkPDFResourceDict::getResourceName(
23292f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org            SkPDFResourceDict::kExtGState_ResourceType,
23392f3e50644221095db9c5052ee359f4565cd4d14commit-bot@chromium.org            objectIndex).c_str());
234e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org    content->writeText(" gs\n");
235e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org}
2369d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org
2379d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org// static
2389d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.orgvoid SkPDFUtils::ApplyPattern(int objectIndex, SkWStream* content) {
2399d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    // Select Pattern color space (CS, cs) and set pattern object as current
2409d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    // color (SCN, scn)
2419d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    SkString resourceName = SkPDFResourceDict::getResourceName(
2429d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org            SkPDFResourceDict::kPattern_ResourceType,
2439d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org            objectIndex);
2449d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    content->writeText("/Pattern CS/Pattern cs/");
2459d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    content->writeText(resourceName.c_str());
2469d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    content->writeText(" SCN/");
2479d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    content->writeText(resourceName.c_str());
2489d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org    content->writeText(" scn\n");
2499d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org}
250