Store content streams in an SkStream instead of an SkString (64k size limit).
Review URL: http://codereview.appspot.com/4272070 git-svn-id: http://skia.googlecode.com/svn/trunk@1011 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
94f6a730bb
commit
cae5fba82e
@ -19,7 +19,7 @@
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkString.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
|
||||
@ -175,7 +175,7 @@ private:
|
||||
struct GraphicStackEntry fGraphicStack[3];
|
||||
int fGraphicStackIndex;
|
||||
|
||||
SkString fContent;
|
||||
SkDynamicMemoryWStream fContent;
|
||||
|
||||
void updateGSFromPaint(const SkPaint& newPaint, bool forText);
|
||||
void updateFont(const SkPaint& paint, uint16_t glyphID);
|
||||
|
@ -151,7 +151,7 @@ public:
|
||||
explicit SkPDFScalar(SkScalar value);
|
||||
virtual ~SkPDFScalar();
|
||||
|
||||
static void Append(SkScalar value, SkString* string);
|
||||
static void Append(SkScalar value, SkWStream* stream);
|
||||
|
||||
// The SkPDFObject interface.
|
||||
virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
|
||||
|
@ -32,19 +32,19 @@ class SkPDFArray;
|
||||
class SkPDFUtils {
|
||||
public:
|
||||
static SkPDFArray* MatrixToArray(const SkMatrix& matrix);
|
||||
|
||||
static void MoveTo(SkScalar x, SkScalar y, SkString* content);
|
||||
static void AppendLine(SkScalar x, SkScalar y, SkString* content);
|
||||
|
||||
static void MoveTo(SkScalar x, SkScalar y, SkWStream* content);
|
||||
static void AppendLine(SkScalar x, SkScalar y, SkWStream* content);
|
||||
static void AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
|
||||
SkScalar ctl2X, SkScalar ctl2Y,
|
||||
SkScalar dstX, SkScalar dstY, SkString* content);
|
||||
SkScalar dstX, SkScalar dstY, SkWStream* content);
|
||||
static void AppendRectangle(SkScalar x, SkScalar y, SkScalar w, SkScalar h,
|
||||
SkString* content);
|
||||
static void EmitPath(const SkPath& path, SkString* content);
|
||||
static void ClosePath(SkString* content);
|
||||
SkWStream* content);
|
||||
static void EmitPath(const SkPath& path, SkWStream* content);
|
||||
static void ClosePath(SkWStream* content);
|
||||
static void PaintPath(SkPaint::Style style, SkPath::FillType fill,
|
||||
SkString* content);
|
||||
static void StrokePath(SkString* content);
|
||||
SkWStream* content);
|
||||
static void StrokePath(SkWStream* content);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -38,20 +38,18 @@
|
||||
|
||||
namespace {
|
||||
|
||||
SkString toPDFColor(SkColor color) {
|
||||
void emitPDFColor(SkColor color, SkWStream* result) {
|
||||
SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere.
|
||||
SkScalar colorMax = SkIntToScalar(0xFF);
|
||||
SkString result;
|
||||
SkPDFScalar::Append(
|
||||
SkScalarDiv(SkIntToScalar(SkColorGetR(color)), colorMax), &result);
|
||||
result.append(" ");
|
||||
SkScalarDiv(SkIntToScalar(SkColorGetR(color)), colorMax), result);
|
||||
result->writeText(" ");
|
||||
SkPDFScalar::Append(
|
||||
SkScalarDiv(SkIntToScalar(SkColorGetG(color)), colorMax), &result);
|
||||
result.append(" ");
|
||||
SkScalarDiv(SkIntToScalar(SkColorGetG(color)), colorMax), result);
|
||||
result->writeText(" ");
|
||||
SkPDFScalar::Append(
|
||||
SkScalarDiv(SkIntToScalar(SkColorGetB(color)), colorMax), &result);
|
||||
result.append(" ");
|
||||
return result;
|
||||
SkScalarDiv(SkIntToScalar(SkColorGetB(color)), colorMax), result);
|
||||
result->writeText(" ");
|
||||
}
|
||||
|
||||
SkPaint calculateTextPaint(const SkPaint& paint) {
|
||||
@ -145,7 +143,9 @@ SkPDFDevice::SkPDFDevice(int width, int height, OriginTransform flipOrigin)
|
||||
fGraphicStack[0].fTransform.reset();
|
||||
|
||||
if (flipOrigin == kFlip_OriginTransform) {
|
||||
fContent.printf("1 0 0 -1 0 %d cm\n", fHeight);
|
||||
fContent.writeText("1 0 0 -1 0 ");
|
||||
fContent.writeDecAsText(fHeight);
|
||||
fContent.writeText(" cm\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,9 +175,9 @@ void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
|
||||
NOT_IMPLEMENTED(clipFill == SkPath::kInverseWinding_FillType,
|
||||
false);
|
||||
if (clipFill == SkPath::kEvenOdd_FillType)
|
||||
fContent.append("W* n ");
|
||||
fContent.writeText("W* n ");
|
||||
else
|
||||
fContent.append("W n ");
|
||||
fContent.writeText("W n ");
|
||||
}
|
||||
|
||||
fGraphicStack[fGraphicStackIndex].fClip = region;
|
||||
@ -339,7 +339,7 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
|
||||
|
||||
SkDrawCacheProc glyphCacheProc = textPaint.getDrawCacheProc();
|
||||
alignText(glyphCacheProc, textPaint, glyphIDs, numGlyphs, &x, &y, widthPtr);
|
||||
fContent.append("BT\n");
|
||||
fContent.writeText("BT\n");
|
||||
setTextTransform(x, y, textPaint.getTextSkewX());
|
||||
size_t consumedGlyphCount = 0;
|
||||
while (numGlyphs > consumedGlyphCount) {
|
||||
@ -348,13 +348,14 @@ void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
|
||||
size_t availableGlyphs =
|
||||
font->glyphsToPDFFontEncoding(glyphIDs + consumedGlyphCount,
|
||||
numGlyphs - consumedGlyphCount);
|
||||
fContent.append(SkPDFString::formatString(glyphIDs + consumedGlyphCount,
|
||||
availableGlyphs,
|
||||
font->multiByteGlyphs()));
|
||||
SkString encodedString =
|
||||
SkPDFString::formatString(glyphIDs + consumedGlyphCount,
|
||||
availableGlyphs, font->multiByteGlyphs());
|
||||
fContent.writeText(encodedString.c_str());
|
||||
consumedGlyphCount += availableGlyphs;
|
||||
fContent.append(" Tj\n");
|
||||
fContent.writeText(" Tj\n");
|
||||
}
|
||||
fContent.append("ET\n");
|
||||
fContent.writeText("ET\n");
|
||||
|
||||
// Draw underline and/or strikethrough if the paint has them.
|
||||
// drawPosText() and drawTextOnPath() don't draw underline or strikethrough
|
||||
@ -402,7 +403,7 @@ void SkPDFDevice::drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
}
|
||||
|
||||
SkDrawCacheProc glyphCacheProc = textPaint.getDrawCacheProc();
|
||||
fContent.append("BT\n");
|
||||
fContent.writeText("BT\n");
|
||||
updateFont(textPaint, glyphIDs[0]);
|
||||
for (size_t i = 0; i < numGlyphs; i++) {
|
||||
SkPDFFont* font = fGraphicStack[fGraphicStackIndex].fFont;
|
||||
@ -416,11 +417,13 @@ void SkPDFDevice::drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar y = scalarsPerPos == 1 ? constY : pos[i * scalarsPerPos + 1];
|
||||
alignText(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y, NULL);
|
||||
setTextTransform(x, y, textPaint.getTextSkewX());
|
||||
fContent.append(SkPDFString::formatString(&encodedValue, 1,
|
||||
font->multiByteGlyphs()));
|
||||
fContent.append(" Tj\n");
|
||||
SkString encodedString =
|
||||
SkPDFString::formatString(&encodedValue, 1,
|
||||
font->multiByteGlyphs());
|
||||
fContent.writeText(encodedString.c_str());
|
||||
fContent.writeText(" Tj\n");
|
||||
}
|
||||
fContent.append("ET\n");
|
||||
fContent.writeText("ET\n");
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
@ -454,9 +457,9 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkDevice* device, int x, int y,
|
||||
|
||||
SkPDFFormXObject* xobject = new SkPDFFormXObject(pdfDevice);
|
||||
fXObjectResources.push(xobject); // Transfer reference.
|
||||
fContent.append("/X");
|
||||
fContent.appendS32(fXObjectResources.count() - 1);
|
||||
fContent.append(" Do\n");
|
||||
fContent.writeText("/X");
|
||||
fContent.writeDecAsText(fXObjectResources.count() - 1);
|
||||
fContent.writeText(" Do\n");
|
||||
setTransform(curTransform);
|
||||
}
|
||||
|
||||
@ -571,9 +574,9 @@ SkRefPtr<SkPDFArray> SkPDFDevice::getMediaBox() const {
|
||||
}
|
||||
|
||||
SkStream* SkPDFDevice::content() const {
|
||||
size_t offset = fContent.size();
|
||||
size_t offset = fContent.getOffset();
|
||||
char* data = (char*)sk_malloc_throw(offset + fGraphicStackIndex * 2);
|
||||
memcpy(data, fContent.c_str(), offset);
|
||||
fContent.copyTo(data);
|
||||
for (int i = 0; i < fGraphicStackIndex; i++) {
|
||||
data[offset++] = 'Q';
|
||||
data[offset++] = '\n';
|
||||
@ -637,8 +640,11 @@ void SkPDFDevice::updateGSFromPaint(const SkPaint& paint, bool forText) {
|
||||
fShaderResources.push(pdfShader.get());
|
||||
pdfShader->ref();
|
||||
}
|
||||
fContent.appendf("/Pattern CS /Pattern cs /P%d SCN /P%d scn\n",
|
||||
resourceIndex, resourceIndex);
|
||||
fContent.writeText("/Pattern CS /Pattern cs /P");
|
||||
fContent.writeDecAsText(resourceIndex);
|
||||
fContent.writeText(" SCN /P");
|
||||
fContent.writeDecAsText(resourceIndex);
|
||||
fContent.writeText(" scn\n");
|
||||
fGraphicStack[fGraphicStackIndex].fShader = pdfShader.get();
|
||||
}
|
||||
} else {
|
||||
@ -646,11 +652,10 @@ void SkPDFDevice::updateGSFromPaint(const SkPaint& paint, bool forText) {
|
||||
newColor = SkColorSetA(newColor, 0xFF);
|
||||
if (fGraphicStack[fGraphicStackIndex].fShader ||
|
||||
fGraphicStack[fGraphicStackIndex].fColor != newColor) {
|
||||
SkString colorString = toPDFColor(newColor);
|
||||
fContent.append(colorString);
|
||||
fContent.append("RG ");
|
||||
fContent.append(colorString);
|
||||
fContent.append("rg\n");
|
||||
emitPDFColor(newColor, &fContent);
|
||||
fContent.writeText("RG ");
|
||||
emitPDFColor(newColor, &fContent);
|
||||
fContent.writeText("rg\n");
|
||||
fGraphicStack[fGraphicStackIndex].fColor = newColor;
|
||||
fGraphicStack[fGraphicStackIndex].fShader = NULL;
|
||||
}
|
||||
@ -669,9 +674,9 @@ void SkPDFDevice::updateGSFromPaint(const SkPaint& paint, bool forText) {
|
||||
fGraphicStateResources.push(newGraphicState.get());
|
||||
newGraphicState->ref();
|
||||
}
|
||||
fContent.append("/G");
|
||||
fContent.appendS32(resourceIndex);
|
||||
fContent.append(" gs\n");
|
||||
fContent.writeText("/G");
|
||||
fContent.writeDecAsText(resourceIndex);
|
||||
fContent.writeText(" gs\n");
|
||||
fGraphicStack[fGraphicStackIndex].fGraphicState = newGraphicState.get();
|
||||
}
|
||||
|
||||
@ -681,7 +686,7 @@ void SkPDFDevice::updateGSFromPaint(const SkPaint& paint, bool forText) {
|
||||
SkScalar scale = newPaint.getTextScaleX();
|
||||
SkScalar pdfScale = SkScalarMul(scale, SkIntToScalar(100));
|
||||
SkPDFScalar::Append(pdfScale, &fContent);
|
||||
fContent.append(" Tz\n");
|
||||
fContent.writeText(" Tz\n");
|
||||
fGraphicStack[fGraphicStackIndex].fTextScaleX = scale;
|
||||
}
|
||||
|
||||
@ -692,8 +697,8 @@ void SkPDFDevice::updateGSFromPaint(const SkPaint& paint, bool forText) {
|
||||
enum_must_match_value);
|
||||
SK_COMPILE_ASSERT(SkPaint::kStrokeAndFill_Style == 2,
|
||||
enum_must_match_value);
|
||||
fContent.appendS32(newPaint.getStyle());
|
||||
fContent.append(" Tr\n");
|
||||
fContent.writeDecAsText(newPaint.getStyle());
|
||||
fContent.writeText(" Tr\n");
|
||||
fGraphicStack[fGraphicStackIndex].fTextFill = newPaint.getStyle();
|
||||
}
|
||||
}
|
||||
@ -706,11 +711,11 @@ void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID) {
|
||||
fGraphicStack[fGraphicStackIndex].fFont->typeface() != typeface ||
|
||||
!fGraphicStack[fGraphicStackIndex].fFont->hasGlyph(glyphID)) {
|
||||
int fontIndex = getFontResourceIndex(typeface, glyphID);
|
||||
fContent.append("/F");
|
||||
fContent.appendS32(fontIndex);
|
||||
fContent.append(" ");
|
||||
fContent.writeText("/F");
|
||||
fContent.writeDecAsText(fontIndex);
|
||||
fContent.writeText(" ");
|
||||
SkPDFScalar::Append(paint.getTextSize(), &fContent);
|
||||
fContent.append(" Tf\n");
|
||||
fContent.writeText(" Tf\n");
|
||||
fGraphicStack[fGraphicStackIndex].fTextSize = paint.getTextSize();
|
||||
fGraphicStack[fGraphicStackIndex].fFont = fFontResources[fontIndex];
|
||||
}
|
||||
@ -730,27 +735,27 @@ int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) {
|
||||
|
||||
void SkPDFDevice::pushGS() {
|
||||
SkASSERT(fGraphicStackIndex < 2);
|
||||
fContent.append("q\n");
|
||||
fContent.writeText("q\n");
|
||||
fGraphicStackIndex++;
|
||||
fGraphicStack[fGraphicStackIndex] = fGraphicStack[fGraphicStackIndex - 1];
|
||||
}
|
||||
|
||||
void SkPDFDevice::popGS() {
|
||||
SkASSERT(fGraphicStackIndex > 0);
|
||||
fContent.append("Q\n");
|
||||
fContent.writeText("Q\n");
|
||||
fGraphicStackIndex--;
|
||||
}
|
||||
|
||||
void SkPDFDevice::setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX) {
|
||||
// Flip the text about the x-axis to account for origin swap and include
|
||||
// the passed parameters.
|
||||
fContent.append("1 0 ");
|
||||
fContent.writeText("1 0 ");
|
||||
SkPDFScalar::Append(0 - textSkewX, &fContent);
|
||||
fContent.append(" -1 ");
|
||||
fContent.writeText(" -1 ");
|
||||
SkPDFScalar::Append(x, &fContent);
|
||||
fContent.append(" ");
|
||||
fContent.writeText(" ");
|
||||
SkPDFScalar::Append(y, &fContent);
|
||||
fContent.append(" Tm\n");
|
||||
fContent.writeText(" Tm\n");
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix,
|
||||
@ -777,9 +782,9 @@ void SkPDFDevice::internalDrawBitmap(const SkMatrix& matrix,
|
||||
updateGSFromPaint(paint, false);
|
||||
|
||||
fXObjectResources.push(image); // Transfer reference.
|
||||
fContent.append("/X");
|
||||
fContent.appendS32(fXObjectResources.count() - 1);
|
||||
fContent.append(" Do\n");
|
||||
fContent.writeText("/X");
|
||||
fContent.writeDecAsText(fXObjectResources.count() - 1);
|
||||
fContent.writeText(" Do\n");
|
||||
setTransform(curTransform);
|
||||
}
|
||||
|
||||
@ -807,9 +812,9 @@ SkMatrix SkPDFDevice::setTransform(const SkMatrix& m) {
|
||||
SkAssertResult(m.pdfTransform(transform));
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(transform); i++) {
|
||||
SkPDFScalar::Append(transform[i], &fContent);
|
||||
fContent.append(" ");
|
||||
fContent.writeText(" ");
|
||||
}
|
||||
fContent.append("cm\n");
|
||||
fContent.writeText("cm\n");
|
||||
fGraphicStack[fGraphicStackIndex].fTransform = m;
|
||||
|
||||
return old;
|
||||
|
@ -236,11 +236,18 @@ SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
|
||||
}
|
||||
|
||||
void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
|
||||
SkString* content) {
|
||||
SkWStream* content) {
|
||||
// Specify width and bounding box for the glyph.
|
||||
SkPDFScalar::Append(width, content);
|
||||
content->appendf(" 0 %d %d %d %d d1\n", box.fLeft, box.fTop,
|
||||
box.fRight, box.fBottom);
|
||||
content->writeText(" 0 ");
|
||||
content->writeDecAsText(box.fLeft);
|
||||
content->writeText(" ");
|
||||
content->writeDecAsText(box.fTop);
|
||||
content->writeText(" ");
|
||||
content->writeDecAsText(box.fRight);
|
||||
content->writeText(" ");
|
||||
content->writeDecAsText(box.fBottom);
|
||||
content->writeText(" d1\n");
|
||||
}
|
||||
|
||||
SkPDFArray* makeFontBBox(
|
||||
@ -670,7 +677,7 @@ void SkPDFFont::populateType3Font(int16_t glyphID) {
|
||||
glyph.fWidth, glyph.fHeight);
|
||||
bbox.join(glyphBBox);
|
||||
|
||||
SkString content;
|
||||
SkDynamicMemoryWStream content;
|
||||
setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox,
|
||||
&content);
|
||||
const SkPath* path = cache->findPath(glyph);
|
||||
@ -679,9 +686,10 @@ void SkPDFFont::populateType3Font(int16_t glyphID) {
|
||||
SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
|
||||
&content);
|
||||
}
|
||||
SkRefPtr<SkStream> glyphStream =
|
||||
new SkMemoryStream(content.c_str(), content.size(), true);
|
||||
SkRefPtr<SkMemoryStream> glyphStream = new SkMemoryStream();
|
||||
glyphStream->unref(); // SkRefPtr and new both took a ref.
|
||||
glyphStream->setMemoryOwned(content.detach(), content.getOffset());
|
||||
|
||||
SkRefPtr<SkPDFStream> glyphDescription =
|
||||
new SkPDFStream(glyphStream.get());
|
||||
// SkRefPtr and new both ref()'d charProcs, pass one.
|
||||
|
@ -100,32 +100,31 @@ void SkPDFScalar::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
|
||||
if (indirect)
|
||||
return emitIndirectObject(stream, catalog);
|
||||
|
||||
SkString tmp;
|
||||
Append(fValue, &tmp);
|
||||
stream->write(tmp.c_str(), tmp.size());
|
||||
Append(fValue, stream);
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFScalar::Append(SkScalar value, SkString* string) {
|
||||
void SkPDFScalar::Append(SkScalar value, SkWStream* stream) {
|
||||
// The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and
|
||||
// +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31).
|
||||
// When using floats that are outside the whole value range, we can use
|
||||
// integers instead.
|
||||
|
||||
|
||||
#if defined(SK_SCALAR_IS_FIXED)
|
||||
string->appendScalar(value);
|
||||
stream->wrieScalarAsText(value);
|
||||
return;
|
||||
#endif // SK_SCALAR_IS_FIXED
|
||||
|
||||
#if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
|
||||
if (value > 32767 || value < -32767) {
|
||||
string->appendS32(SkScalarRound(value));
|
||||
stream->writeDecAsText(SkScalarRound(value));
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[SkStrAppendScalar_MaxSize];
|
||||
char* end = SkStrAppendFixed(buffer, SkScalarToFixed(value));
|
||||
string->append(buffer, end - buffer);
|
||||
stream->write(buffer, end - buffer);
|
||||
return;
|
||||
#endif // !SK_ALLOW_LARGE_PDF_SCALARS
|
||||
|
||||
@ -134,12 +133,12 @@ void SkPDFScalar::Append(SkScalar value, SkString* string) {
|
||||
// no more precise than an int. (Plus PDF doesn't support scientific
|
||||
// notation, so this clamps to SK_Max/MinS32).
|
||||
if (value > (1 << 24) || value < -(1 << 24)) {
|
||||
string->appendS32(value);
|
||||
stream->writeDecAsText(value);
|
||||
return;
|
||||
}
|
||||
// Continue to enforce the PDF limits for small floats.
|
||||
if (value < 1.0f/65536 && value > -1.0f/65536) {
|
||||
string->appendS32(0);
|
||||
stream->writeDecAsText(0);
|
||||
return;
|
||||
}
|
||||
// SkStrAppendFloat might still use scientific notation, so use snprintf
|
||||
@ -154,7 +153,7 @@ void SkPDFScalar::Append(SkScalar value, SkString* string) {
|
||||
if (buffer[len - 1] == '.') {
|
||||
buffer[len - 1] = '\0';
|
||||
}
|
||||
string->append(buffer);
|
||||
stream->writeText(buffer);
|
||||
return;
|
||||
#endif // SK_SCALAR_IS_FLOAT && SK_ALLOW_LARGE_PDF_SCALARS
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPDFUtils.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkString.h"
|
||||
#include "SkPDFTypes.h"
|
||||
|
||||
@ -34,59 +35,59 @@ SkPDFArray* SkPDFUtils::MatrixToArray(const SkMatrix& matrix) {
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkString* content) {
|
||||
void SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkWStream* content) {
|
||||
SkPDFScalar::Append(x, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(y, content);
|
||||
content->append(" m\n");
|
||||
content->writeText(" m\n");
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkString* content) {
|
||||
void SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkWStream* content) {
|
||||
SkPDFScalar::Append(x, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(y, content);
|
||||
content->append(" l\n");
|
||||
content->writeText(" l\n");
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
|
||||
SkScalar ctl2X, SkScalar ctl2Y,
|
||||
SkScalar dstX, SkScalar dstY, SkString* content) {
|
||||
SkScalar dstX, SkScalar dstY, SkWStream* content) {
|
||||
SkString cmd("y\n");
|
||||
SkPDFScalar::Append(ctl1X, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(ctl1Y, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
if (ctl2X != dstX || ctl2Y != dstY) {
|
||||
cmd.set("c\n");
|
||||
SkPDFScalar::Append(ctl2X, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(ctl2Y, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
}
|
||||
SkPDFScalar::Append(dstX, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(dstY, content);
|
||||
content->append(" ");
|
||||
content->append(cmd);
|
||||
content->writeText(" ");
|
||||
content->writeText(cmd.c_str());
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::AppendRectangle(SkScalar x, SkScalar y,
|
||||
SkScalar w, SkScalar h, SkString* content) {
|
||||
SkScalar w, SkScalar h, SkWStream* content) {
|
||||
SkPDFScalar::Append(x, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(y, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(w, content);
|
||||
content->append(" ");
|
||||
content->writeText(" ");
|
||||
SkPDFScalar::Append(h, content);
|
||||
content->append(" re\n");
|
||||
content->writeText(" re\n");
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::EmitPath(const SkPath& path, SkString* content) {
|
||||
// static
|
||||
void SkPDFUtils::EmitPath(const SkPath& path, SkWStream* content) {
|
||||
SkPoint args[4];
|
||||
SkPath::Iter iter(path, false);
|
||||
for (SkPath::Verb verb = iter.next(args);
|
||||
@ -129,32 +130,31 @@ void SkPDFUtils::EmitPath(const SkPath& path, SkString* content) {
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::ClosePath(SkString* content) {
|
||||
content->append("h\n");
|
||||
void SkPDFUtils::ClosePath(SkWStream* content) {
|
||||
content->writeText("h\n");
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::PaintPath(SkPaint::Style style, SkPath::FillType fill,
|
||||
SkString* content) {
|
||||
SkWStream* content) {
|
||||
if (style == SkPaint::kFill_Style)
|
||||
content->append("f");
|
||||
content->writeText("f");
|
||||
else if (style == SkPaint::kStrokeAndFill_Style)
|
||||
content->append("B");
|
||||
content->writeText("B");
|
||||
else if (style == SkPaint::kStroke_Style)
|
||||
content->append("S");
|
||||
content->writeText("S");
|
||||
|
||||
if (style != SkPaint::kStroke_Style) {
|
||||
// Not supported yet.
|
||||
NOT_IMPLEMENTED(fill == SkPath::kInverseEvenOdd_FillType, false);
|
||||
NOT_IMPLEMENTED(fill == SkPath::kInverseWinding_FillType, false);
|
||||
if (fill == SkPath::kEvenOdd_FillType)
|
||||
content->append("*");
|
||||
content->writeText("*");
|
||||
}
|
||||
content->append("\n");
|
||||
content->writeText("\n");
|
||||
}
|
||||
|
||||
// static
|
||||
void SkPDFUtils::StrokePath(SkString* content) {
|
||||
void SkPDFUtils::StrokePath(SkWStream* content) {
|
||||
SkPDFUtils::PaintPath(
|
||||
SkPaint::kStroke_Style, SkPath::kWinding_FillType, content);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user