1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkScanPriv_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkScanPriv_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScan.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitter.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkScanClipper {
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
175ee6491b7a1e7c177abc0186c2749ebe1f71fcf7reed@google.com    SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
185ee6491b7a1e7c177abc0186c2749ebe1f71fcf7reed@google.com                  bool skipRejectTest = false);
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBlitter*      getBlitter() const { return fBlitter; }
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkIRect*  getClipRect() const { return fClipRect; }
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRectClipBlitter   fRectBlitter;
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRgnClipBlitter    fRgnBlitter;
2628930b46487fc94fde206d1283623204c595b0f1Mike Reed#ifdef SK_DEBUG
2799bba9ea829323a7941d4f3a9c98da7a76432d1bYuqian Li    SkRectClipCheckBlitter fRectClipCheckBlitter;
2828930b46487fc94fde206d1283623204c595b0f1Mike Reed#endif
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBlitter*          fBlitter;
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkIRect*      fClipRect;
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
33e4b8b5283f45cff6a490ee73677f75b641c22bd1Yuqian Livoid sk_fill_path(const SkPath& path, const SkIRect& clipRect,
34dca6a56b71b922aab32098d6a55bbb041f3a2b48reed@android.com                  SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
35e4b8b5283f45cff6a490ee73677f75b641c22bd1Yuqian Li                  bool pathContainedInClip);
36e4b8b5283f45cff6a490ee73677f75b641c22bd1Yuqian Li
3755b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.com// blit the rects above and below avoid, clipped to clip
3855b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.comvoid sk_blit_above(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
3955b6b58d8f6e7529c9b9cea606a6e3637c8e2e39reed@google.comvoid sk_blit_below(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
41a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Litemplate<class EdgeType>
42a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Listatic inline void remove_edge(EdgeType* edge) {
43a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    edge->fPrev->fNext = edge->fNext;
44a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    edge->fNext->fPrev = edge->fPrev;
45a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li}
46a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li
47a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Litemplate<class EdgeType>
48a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Listatic inline void insert_edge_after(EdgeType* edge, EdgeType* afterMe) {
49a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    edge->fPrev = afterMe;
50a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    edge->fNext = afterMe->fNext;
51a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    afterMe->fNext->fPrev = edge;
52a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    afterMe->fNext = edge;
53a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li}
54a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li
55a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Litemplate<class EdgeType>
56a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Listatic void backward_insert_edge_based_on_x(EdgeType* edge) {
57a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    SkFixed x = edge->fX;
58a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    EdgeType* prev = edge->fPrev;
59a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    while (prev->fPrev && prev->fX > x) {
60a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li        prev = prev->fPrev;
61a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    }
62a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    if (prev->fNext != edge) {
63a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li        remove_edge(edge);
64a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li        insert_edge_after(edge, prev);
65a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    }
66a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li}
67a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li
68a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li// Start from the right side, searching backwards for the point to begin the new edge list
69a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li// insertion, marching forwards from here. The implementation could have started from the left
70a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li// of the prior insertion, and search to the right, or with some additional caching, binary
71a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li// search the starting point. More work could be done to determine optimal new edge insertion.
72a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Litemplate<class EdgeType>
73a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Listatic EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
74a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    while (prev->fPrev && prev->fX > x) {
75a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li        prev = prev->fPrev;
76a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    }
77a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li    return prev;
78a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li}
79a33b43d796f03e2f4b5abd8060272f4f775d7390Yuqian Li
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
81