gfx/skia/trunk/src/core/SkEdgeBuilder.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  */
     8 #include "SkEdgeBuilder.h"
     9 #include "SkPath.h"
    10 #include "SkEdge.h"
    11 #include "SkEdgeClipper.h"
    12 #include "SkLineClipper.h"
    13 #include "SkGeometry.h"
    15 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) {
    16     return static_cast<T*>(alloc.allocThrow(sizeof(T)));
    17 }
    19 ///////////////////////////////////////////////////////////////////////////////
    21 SkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) {
    22     fEdgeList = NULL;
    23 }
    25 void SkEdgeBuilder::addLine(const SkPoint pts[]) {
    26     SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
    27     if (edge->setLine(pts[0], pts[1], fShiftUp)) {
    28         fList.push(edge);
    29     } else {
    30         // TODO: unallocate edge from storage...
    31     }
    32 }
    34 void SkEdgeBuilder::addQuad(const SkPoint pts[]) {
    35     SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc);
    36     if (edge->setQuadratic(pts, fShiftUp)) {
    37         fList.push(edge);
    38     } else {
    39         // TODO: unallocate edge from storage...
    40     }
    41 }
    43 void SkEdgeBuilder::addCubic(const SkPoint pts[]) {
    44     SkCubicEdge* edge = typedAllocThrow<SkCubicEdge>(fAlloc);
    45     if (edge->setCubic(pts, NULL, fShiftUp)) {
    46         fList.push(edge);
    47     } else {
    48         // TODO: unallocate edge from storage...
    49     }
    50 }
    52 void SkEdgeBuilder::addClipper(SkEdgeClipper* clipper) {
    53     SkPoint      pts[4];
    54     SkPath::Verb verb;
    56     while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) {
    57         switch (verb) {
    58             case SkPath::kLine_Verb:
    59                 this->addLine(pts);
    60                 break;
    61             case SkPath::kQuad_Verb:
    62                 this->addQuad(pts);
    63                 break;
    64             case SkPath::kCubic_Verb:
    65                 this->addCubic(pts);
    66                 break;
    67             default:
    68                 break;
    69         }
    70     }
    71 }
    73 ///////////////////////////////////////////////////////////////////////////////
    75 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
    76     dst->set(SkIntToScalar(src.fLeft >> shift),
    77              SkIntToScalar(src.fTop >> shift),
    78              SkIntToScalar(src.fRight >> shift),
    79              SkIntToScalar(src.fBottom >> shift));
    80 }
    82 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip,
    83                              int shiftUp) {
    84     SkPath::Iter    iter(path, true);
    85     SkPoint         pts[4];
    86     SkPath::Verb    verb;
    88     int maxEdgeCount = path.countPoints();
    89     if (iclip) {
    90         // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
    91         // we turn portions that are clipped out on the left/right into vertical
    92         // segments.
    93         maxEdgeCount *= SkLineClipper::kMaxClippedLineSegments;
    94     }
    95     size_t maxEdgeSize = maxEdgeCount * sizeof(SkEdge);
    96     size_t maxEdgePtrSize = maxEdgeCount * sizeof(SkEdge*);
    98     // lets store the edges and their pointers in the same block
    99     char* storage = (char*)fAlloc.allocThrow(maxEdgeSize + maxEdgePtrSize);
   100     SkEdge* edge = reinterpret_cast<SkEdge*>(storage);
   101     SkEdge** edgePtr = reinterpret_cast<SkEdge**>(storage + maxEdgeSize);
   102     // Record the beginning of our pointers, so we can return them to the caller
   103     fEdgeList = edgePtr;
   105     if (iclip) {
   106         SkRect clip;
   107         setShiftedClip(&clip, *iclip, shiftUp);
   109         while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
   110             switch (verb) {
   111                 case SkPath::kMove_Verb:
   112                 case SkPath::kClose_Verb:
   113                     // we ignore these, and just get the whole segment from
   114                     // the corresponding line/quad/cubic verbs
   115                     break;
   116                 case SkPath::kLine_Verb: {
   117                     SkPoint lines[SkLineClipper::kMaxPoints];
   118                     int lineCount = SkLineClipper::ClipLine(pts, clip, lines);
   119                     SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments);
   120                     for (int i = 0; i < lineCount; i++) {
   121                         if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
   122                             *edgePtr++ = edge++;
   123                         }
   124                     }
   125                     break;
   126                 }
   127                 default:
   128                     SkDEBUGFAIL("unexpected verb");
   129                     break;
   130             }
   131         }
   132     } else {
   133         while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
   134             switch (verb) {
   135                 case SkPath::kMove_Verb:
   136                 case SkPath::kClose_Verb:
   137                     // we ignore these, and just get the whole segment from
   138                     // the corresponding line/quad/cubic verbs
   139                     break;
   140                 case SkPath::kLine_Verb:
   141                     if (edge->setLine(pts[0], pts[1], shiftUp)) {
   142                         *edgePtr++ = edge++;
   143                     }
   144                     break;
   145                 default:
   146                     SkDEBUGFAIL("unexpected verb");
   147                     break;
   148             }
   149         }
   150     }
   151     SkASSERT((char*)edge <= (char*)fEdgeList);
   152     SkASSERT(edgePtr - fEdgeList <= maxEdgeCount);
   153     return SkToInt(edgePtr - fEdgeList);
   154 }
   156 static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
   157     SkPoint monoX[5];
   158     int n = SkChopQuadAtYExtrema(pts, monoX);
   159     for (int i = 0; i <= n; i++) {
   160         builder->addQuad(&monoX[i * 2]);
   161     }
   162 }
   164 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip,
   165                          int shiftUp) {
   166     fAlloc.reset();
   167     fList.reset();
   168     fShiftUp = shiftUp;
   170     SkScalar conicTol = SK_ScalarHalf * (1 << shiftUp);
   172     if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
   173         return this->buildPoly(path, iclip, shiftUp);
   174     }
   176     SkPath::Iter    iter(path, true);
   177     SkPoint         pts[4];
   178     SkPath::Verb    verb;
   180     if (iclip) {
   181         SkRect clip;
   182         setShiftedClip(&clip, *iclip, shiftUp);
   183         SkEdgeClipper clipper;
   185         while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
   186             switch (verb) {
   187                 case SkPath::kMove_Verb:
   188                 case SkPath::kClose_Verb:
   189                     // we ignore these, and just get the whole segment from
   190                     // the corresponding line/quad/cubic verbs
   191                     break;
   192                 case SkPath::kLine_Verb: {
   193                     SkPoint lines[SkLineClipper::kMaxPoints];
   194                     int lineCount = SkLineClipper::ClipLine(pts, clip, lines);
   195                     for (int i = 0; i < lineCount; i++) {
   196                         this->addLine(&lines[i]);
   197                     }
   198                     break;
   199                 }
   200                 case SkPath::kQuad_Verb:
   201                     if (clipper.clipQuad(pts, clip)) {
   202                         this->addClipper(&clipper);
   203                     }
   204                     break;
   205                 case SkPath::kConic_Verb: {
   206                     const int MAX_POW2 = 4;
   207                     const int MAX_QUADS = 1 << MAX_POW2;
   208                     const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS;
   209                     SkPoint storage[MAX_QUAD_PTS];
   211                     SkConic conic;
   212                     conic.set(pts, iter.conicWeight());
   213                     int pow2 = conic.computeQuadPOW2(conicTol);
   214                     pow2 = SkMin32(pow2, MAX_POW2);
   215                     int quadCount = conic.chopIntoQuadsPOW2(storage, pow2);
   216                     SkASSERT(quadCount <= MAX_QUADS);
   217                     for (int i = 0; i < quadCount; ++i) {
   218                         if (clipper.clipQuad(&storage[i * 2], clip)) {
   219                             this->addClipper(&clipper);
   220                         }
   221                     }
   222                 } break;
   223                 case SkPath::kCubic_Verb:
   224                     if (clipper.clipCubic(pts, clip)) {
   225                         this->addClipper(&clipper);
   226                     }
   227                     break;
   228                 default:
   229                     SkDEBUGFAIL("unexpected verb");
   230                     break;
   231             }
   232         }
   233     } else {
   234         while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
   235             switch (verb) {
   236                 case SkPath::kMove_Verb:
   237                 case SkPath::kClose_Verb:
   238                     // we ignore these, and just get the whole segment from
   239                     // the corresponding line/quad/cubic verbs
   240                     break;
   241                 case SkPath::kLine_Verb:
   242                     this->addLine(pts);
   243                     break;
   244                 case SkPath::kQuad_Verb: {
   245                     handle_quad(this, pts);
   246                     break;
   247                 }
   248                 case SkPath::kConic_Verb: {
   249                     const int MAX_POW2 = 4;
   250                     const int MAX_QUADS = 1 << MAX_POW2;
   251                     const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS;
   252                     SkPoint storage[MAX_QUAD_PTS];
   254                     SkConic conic;
   255                     conic.set(pts, iter.conicWeight());
   256                     int pow2 = conic.computeQuadPOW2(conicTol);
   257                     pow2 = SkMin32(pow2, MAX_POW2);
   258                     int quadCount = conic.chopIntoQuadsPOW2(storage, pow2);
   259                     SkASSERT(quadCount <= MAX_QUADS);
   260                     for (int i = 0; i < quadCount; ++i) {
   261                         handle_quad(this, &storage[i * 2]);
   262                     }
   263                 } break;
   264                 case SkPath::kCubic_Verb: {
   265                     SkPoint monoY[10];
   266                     int n = SkChopCubicAtYExtrema(pts, monoY);
   267                     for (int i = 0; i <= n; i++) {
   268                         this->addCubic(&monoY[i * 3]);
   269                     }
   270                     break;
   271                 }
   272                 default:
   273                     SkDEBUGFAIL("unexpected verb");
   274                     break;
   275             }
   276         }
   277     }
   278     fEdgeList = fList.begin();
   279     return fList.count();
   280 }

mercurial