gfx/skia/trunk/src/pdf/SkPDFUtils.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     2 /*
     3  * Copyright 2011 Google Inc.
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    10 #include "SkData.h"
    11 #include "SkGeometry.h"
    12 #include "SkPaint.h"
    13 #include "SkPath.h"
    14 #include "SkPDFResourceDict.h"
    15 #include "SkPDFUtils.h"
    16 #include "SkStream.h"
    17 #include "SkString.h"
    18 #include "SkPDFTypes.h"
    20 //static
    21 SkPDFArray* SkPDFUtils::RectToArray(const SkRect& rect) {
    22     SkPDFArray* result = new SkPDFArray();
    23     result->reserve(4);
    24     result->appendScalar(rect.fLeft);
    25     result->appendScalar(rect.fTop);
    26     result->appendScalar(rect.fRight);
    27     result->appendScalar(rect.fBottom);
    28     return result;
    29 }
    31 // static
    32 SkPDFArray* SkPDFUtils::MatrixToArray(const SkMatrix& matrix) {
    33     SkScalar values[6];
    34     if (!matrix.asAffine(values)) {
    35         SkMatrix::SetAffineIdentity(values);
    36     }
    38     SkPDFArray* result = new SkPDFArray;
    39     result->reserve(6);
    40     for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) {
    41         result->appendScalar(values[i]);
    42     }
    43     return result;
    44 }
    46 // static
    47 void SkPDFUtils::AppendTransform(const SkMatrix& matrix, SkWStream* content) {
    48     SkScalar values[6];
    49     if (!matrix.asAffine(values)) {
    50         SkMatrix::SetAffineIdentity(values);
    51     }
    52     for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) {
    53         SkPDFScalar::Append(values[i], content);
    54         content->writeText(" ");
    55     }
    56     content->writeText("cm\n");
    57 }
    59 // static
    60 void SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkWStream* content) {
    61     SkPDFScalar::Append(x, content);
    62     content->writeText(" ");
    63     SkPDFScalar::Append(y, content);
    64     content->writeText(" m\n");
    65 }
    67 // static
    68 void SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkWStream* content) {
    69     SkPDFScalar::Append(x, content);
    70     content->writeText(" ");
    71     SkPDFScalar::Append(y, content);
    72     content->writeText(" l\n");
    73 }
    75 // static
    76 void SkPDFUtils::AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
    77                              SkScalar ctl2X, SkScalar ctl2Y,
    78                              SkScalar dstX, SkScalar dstY, SkWStream* content) {
    79     SkString cmd("y\n");
    80     SkPDFScalar::Append(ctl1X, content);
    81     content->writeText(" ");
    82     SkPDFScalar::Append(ctl1Y, content);
    83     content->writeText(" ");
    84     if (ctl2X != dstX || ctl2Y != dstY) {
    85         cmd.set("c\n");
    86         SkPDFScalar::Append(ctl2X, content);
    87         content->writeText(" ");
    88         SkPDFScalar::Append(ctl2Y, content);
    89         content->writeText(" ");
    90     }
    91     SkPDFScalar::Append(dstX, content);
    92     content->writeText(" ");
    93     SkPDFScalar::Append(dstY, content);
    94     content->writeText(" ");
    95     content->writeText(cmd.c_str());
    96 }
    98 // static
    99 void SkPDFUtils::AppendRectangle(const SkRect& rect, SkWStream* content) {
   100     // Skia has 0,0 at top left, pdf at bottom left.  Do the right thing.
   101     SkScalar bottom = SkMinScalar(rect.fBottom, rect.fTop);
   103     SkPDFScalar::Append(rect.fLeft, content);
   104     content->writeText(" ");
   105     SkPDFScalar::Append(bottom, content);
   106     content->writeText(" ");
   107     SkPDFScalar::Append(rect.width(), content);
   108     content->writeText(" ");
   109     SkPDFScalar::Append(rect.height(), content);
   110     content->writeText(" re\n");
   111 }
   113 // static
   114 void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
   115                           SkWStream* content) {
   116     // Filling a path with no area results in a drawing in PDF renderers but
   117     // Chrome expects to be able to draw some such entities with no visible
   118     // result, so we detect those cases and discard the drawing for them.
   119     // Specifically: moveTo(X), lineTo(Y) and moveTo(X), lineTo(X), lineTo(Y).
   120     enum SkipFillState {
   121         kEmpty_SkipFillState         = 0,
   122         kSingleLine_SkipFillState    = 1,
   123         kNonSingleLine_SkipFillState = 2,
   124     };
   125     SkipFillState fillState = kEmpty_SkipFillState;
   126     if (paintStyle != SkPaint::kFill_Style) {
   127         fillState = kNonSingleLine_SkipFillState;
   128     }
   129     SkPoint lastMovePt = SkPoint::Make(0,0);
   130     SkDynamicMemoryWStream currentSegment;
   131     SkPoint args[4];
   132     SkPath::Iter iter(path, false);
   133     for (SkPath::Verb verb = iter.next(args);
   134          verb != SkPath::kDone_Verb;
   135          verb = iter.next(args)) {
   136         // args gets all the points, even the implicit first point.
   137         switch (verb) {
   138             case SkPath::kMove_Verb:
   139                 MoveTo(args[0].fX, args[0].fY, &currentSegment);
   140                 lastMovePt = args[0];
   141                 fillState = kEmpty_SkipFillState;
   142                 break;
   143             case SkPath::kLine_Verb:
   144                 AppendLine(args[1].fX, args[1].fY, &currentSegment);
   145                 if (fillState == kEmpty_SkipFillState) {
   146                    if (args[0] != lastMovePt) {
   147                        fillState = kSingleLine_SkipFillState;
   148                    }
   149                 } else if (fillState == kSingleLine_SkipFillState) {
   150                     fillState = kNonSingleLine_SkipFillState;
   151                 }
   152                 break;
   153             case SkPath::kQuad_Verb: {
   154                 SkPoint cubic[4];
   155                 SkConvertQuadToCubic(args, cubic);
   156                 AppendCubic(cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY,
   157                             cubic[3].fX, cubic[3].fY, &currentSegment);
   158                 fillState = kNonSingleLine_SkipFillState;
   159                 break;
   160             }
   161             case SkPath::kCubic_Verb:
   162                 AppendCubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY,
   163                             args[3].fX, args[3].fY, &currentSegment);
   164                 fillState = kNonSingleLine_SkipFillState;
   165                 break;
   166             case SkPath::kClose_Verb:
   167                 if (fillState != kSingleLine_SkipFillState) {
   168                     ClosePath(&currentSegment);
   169                     SkData* data = currentSegment.copyToData();
   170                     content->write(data->data(), data->size());
   171                     data->unref();
   172                 }
   173                 currentSegment.reset();
   174                 break;
   175             default:
   176                 SkASSERT(false);
   177                 break;
   178         }
   179     }
   180     if (currentSegment.bytesWritten() > 0) {
   181         SkData* data = currentSegment.copyToData();
   182         content->write(data->data(), data->size());
   183         data->unref();
   184     }
   185 }
   187 // static
   188 void SkPDFUtils::ClosePath(SkWStream* content) {
   189     content->writeText("h\n");
   190 }
   192 // static
   193 void SkPDFUtils::PaintPath(SkPaint::Style style, SkPath::FillType fill,
   194                            SkWStream* content) {
   195     if (style == SkPaint::kFill_Style) {
   196         content->writeText("f");
   197     } else if (style == SkPaint::kStrokeAndFill_Style) {
   198         content->writeText("B");
   199     } else if (style == SkPaint::kStroke_Style) {
   200         content->writeText("S");
   201     }
   203     if (style != SkPaint::kStroke_Style) {
   204         NOT_IMPLEMENTED(fill == SkPath::kInverseEvenOdd_FillType, false);
   205         NOT_IMPLEMENTED(fill == SkPath::kInverseWinding_FillType, false);
   206         if (fill == SkPath::kEvenOdd_FillType) {
   207             content->writeText("*");
   208         }
   209     }
   210     content->writeText("\n");
   211 }
   213 // static
   214 void SkPDFUtils::StrokePath(SkWStream* content) {
   215     SkPDFUtils::PaintPath(
   216         SkPaint::kStroke_Style, SkPath::kWinding_FillType, content);
   217 }
   219 // static
   220 void SkPDFUtils::DrawFormXObject(int objectIndex, SkWStream* content) {
   221     content->writeText("/");
   222     content->writeText(SkPDFResourceDict::getResourceName(
   223             SkPDFResourceDict::kXObject_ResourceType,
   224             objectIndex).c_str());
   225     content->writeText(" Do\n");
   226 }
   228 // static
   229 void SkPDFUtils::ApplyGraphicState(int objectIndex, SkWStream* content) {
   230     content->writeText("/");
   231     content->writeText(SkPDFResourceDict::getResourceName(
   232             SkPDFResourceDict::kExtGState_ResourceType,
   233             objectIndex).c_str());
   234     content->writeText(" gs\n");
   235 }
   237 // static
   238 void SkPDFUtils::ApplyPattern(int objectIndex, SkWStream* content) {
   239     // Select Pattern color space (CS, cs) and set pattern object as current
   240     // color (SCN, scn)
   241     SkString resourceName = SkPDFResourceDict::getResourceName(
   242             SkPDFResourceDict::kPattern_ResourceType,
   243             objectIndex);
   244     content->writeText("/Pattern CS/Pattern cs/");
   245     content->writeText(resourceName.c_str());
   246     content->writeText(" SCN/");
   247     content->writeText(resourceName.c_str());
   248     content->writeText(" scn\n");
   249 }

mercurial