//========================================================================
//
// SplashXPathScanner.cc
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2008, 2010, 2014, 2018, 2019, 2021 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
// Copyright (C) 2013, 2014, 2021 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2018 Stefan Brüns <stefan.bruens@rwth-aachen.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <config.h>

#include <cstdlib>
#include <cstring>
#include <algorithm>
#include "goo/gmem.h"
#include "SplashMath.h"
#include "SplashXPath.h"
#include "SplashBitmap.h"
#include "SplashXPathScanner.h"

//------------------------------------------------------------------------

//------------------------------------------------------------------------
// SplashXPathScanner
//------------------------------------------------------------------------

SplashXPathScanner::SplashXPathScanner(const SplashXPath &xPath, bool eoA, int clipYMin, int clipYMax)
{
    const SplashXPathSeg *seg;
    SplashCoord xMinFP, yMinFP, xMaxFP, yMaxFP;
    int i;

    eo = eoA;
    partialClip = false;

    // compute the bbox
    xMin = yMin = 1;
    xMax = yMax = 0;
    if (xPath.length > 0) {
        seg = &xPath.segs[0];
        if (unlikely(std::isnan(seg->x0) || std::isnan(seg->x1) || std::isnan(seg->y0) || std::isnan(seg->y1))) {
            return;
        }
        if (seg->x0 <= seg->x1) {
            xMinFP = seg->x0;
            xMaxFP = seg->x1;
        } else {
            xMinFP = seg->x1;
            xMaxFP = seg->x0;
        }
        if (seg->flags & splashXPathFlip) {
            yMinFP = seg->y1;
            yMaxFP = seg->y0;
        } else {
            yMinFP = seg->y0;
            yMaxFP = seg->y1;
        }
        for (i = 1; i < xPath.length; ++i) {
            seg = &xPath.segs[i];
            if (unlikely(std::isnan(seg->x0) || std::isnan(seg->x1) || std::isnan(seg->y0) || std::isnan(seg->y1))) {
                return;
            }
            if (seg->x0 < xMinFP) {
                xMinFP = seg->x0;
            } else if (seg->x0 > xMaxFP) {
                xMaxFP = seg->x0;
            }
            if (seg->x1 < xMinFP) {
                xMinFP = seg->x1;
            } else if (seg->x1 > xMaxFP) {
                xMaxFP = seg->x1;
            }
            if (seg->flags & splashXPathFlip) {
                if (seg->y0 > yMaxFP) {
                    yMaxFP = seg->y0;
                }
            } else {
                if (seg->y1 > yMaxFP) {
                    yMaxFP = seg->y1;
                }
            }
        }
        xMin = splashFloor(xMinFP);
        xMax = splashFloor(xMaxFP);
        yMin = splashFloor(yMinFP);
        yMax = splashFloor(yMaxFP);
        if (clipYMin > yMin) {
            yMin = clipYMin;
            partialClip = true;
        }
        if (clipYMax < yMax) {
            yMax = clipYMax;
            partialClip = true;
        }
    }

    computeIntersections(xPath);
}

SplashXPathScanner::~SplashXPathScanner() { }

void SplashXPathScanner::getBBoxAA(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) const
{
    *xMinA = xMin / splashAASize;
    *yMinA = yMin / splashAASize;
    *xMaxA = xMax / splashAASize;
    *yMaxA = yMax / splashAASize;
}

void SplashXPathScanner::getSpanBounds(int y, int *spanXMin, int *spanXMax) const
{
    if (y < yMin || y > yMax) {
        *spanXMin = xMax + 1;
        *spanXMax = xMax;
        return;
    }
    const auto &line = allIntersections[y - yMin];
    if (!line.empty()) {
        *spanXMin = line[0].x0;
        int xx = line[0].x1;
        for (const SplashIntersect &intersect : line) {
            if (intersect.x1 > xx) {
                xx = intersect.x1;
            }
        }
        *spanXMax = xx;
    } else {
        *spanXMin = xMax + 1;
        *spanXMax = xMax;
    }
}

bool SplashXPathScanner::test(int x, int y) const
{
    if (y < yMin || y > yMax) {
        return false;
    }
    const auto &line = allIntersections[y - yMin];
    int count = 0;
    for (unsigned int i = 0; i < line.size() && line[i].x0 <= x; ++i) {
        if (x <= line[i].x1) {
            return true;
        }
        count += line[i].count;
    }
    return eo ? (count & 1) : (count != 0);
}

bool SplashXPathScanner::testSpan(int x0, int x1, int y) const
{
    unsigned int i;

    if (y < yMin || y > yMax) {
        return false;
    }
    const auto &line = allIntersections[y - yMin];
    int count = 0;
    for (i = 0; i < line.size() && line[i].x1 < x0; ++i) {
        count += line[i].count;
    }

    // invariant: the subspan [x0,xx1] is inside the path
    int xx1 = x0 - 1;
    while (xx1 < x1) {
        if (i >= line.size()) {
            return false;
        }
        if (line[i].x0 > xx1 + 1 && !(eo ? (count & 1) : (count != 0))) {
            return false;
        }
        if (line[i].x1 > xx1) {
            xx1 = line[i].x1;
        }
        count += line[i].count;
        ++i;
    }

    return true;
}

bool SplashXPathScanIterator::getNextSpan(int *x0, int *x1)
{
    int xx0, xx1;

    if (interIdx >= line.size()) {
        return false;
    }
    xx0 = line[interIdx].x0;
    xx1 = line[interIdx].x1;
    interCount += line[interIdx].count;
    ++interIdx;
    while (interIdx < line.size() && (line[interIdx].x0 <= xx1 || (eo ? (interCount & 1) : (interCount != 0)))) {
        if (line[interIdx].x1 > xx1) {
            xx1 = line[interIdx].x1;
        }
        interCount += line[interIdx].count;
        ++interIdx;
    }
    *x0 = xx0;
    *x1 = xx1;
    return true;
}

SplashXPathScanIterator::SplashXPathScanIterator(const SplashXPathScanner &scanner, int y)
    : line((y < scanner.yMin || y > scanner.yMax) ? scanner.allIntersections[0] : scanner.allIntersections[y - scanner.yMin]), interIdx(0), interCount(0), eo(scanner.eo)
{
    if (y < scanner.yMin || y > scanner.yMax) {
        // set index to line end
        interIdx = line.size();
    }
}

void SplashXPathScanner::computeIntersections(const SplashXPath &xPath)
{
    const SplashXPathSeg *seg;
    SplashCoord segXMin, segXMax, segYMin, segYMax, xx0, xx1;
    int x, y, y0, y1, i;

    if (yMin > yMax) {
        return;
    }

    // build the list of all intersections
    allIntersections.resize(yMax - yMin + 1);

    for (i = 0; i < xPath.length; ++i) {
        seg = &xPath.segs[i];
        if (seg->flags & splashXPathFlip) {
            segYMin = seg->y1;
            segYMax = seg->y0;
        } else {
            segYMin = seg->y0;
            segYMax = seg->y1;
        }
        if (seg->flags & splashXPathHoriz) {
            y = splashFloor(seg->y0);
            if (y >= yMin && y <= yMax) {
                if (!addIntersection(segYMin, segYMax, y, splashFloor(seg->x0), splashFloor(seg->x1), 0))
                    break;
            }
        } else if (seg->flags & splashXPathVert) {
            y0 = splashFloor(segYMin);
            if (y0 < yMin) {
                y0 = yMin;
            }
            y1 = splashFloor(segYMax);
            if (y1 > yMax) {
                y1 = yMax;
            }
            x = splashFloor(seg->x0);
            int count = eo || (seg->flags & splashXPathFlip) ? 1 : -1;
            for (y = y0; y <= y1; ++y) {
                if (!addIntersection(segYMin, segYMax, y, x, x, count))
                    break;
            }
        } else {
            if (seg->x0 < seg->x1) {
                segXMin = seg->x0;
                segXMax = seg->x1;
            } else {
                segXMin = seg->x1;
                segXMax = seg->x0;
            }
            y0 = splashFloor(segYMin);
            if (y0 < yMin) {
                y0 = yMin;
            }
            y1 = splashFloor(segYMax);
            if (y1 > yMax) {
                y1 = yMax;
            }
            int count = eo || (seg->flags & splashXPathFlip) ? 1 : -1;
            // Calculate the projected intersection of the segment with the
            // X-Axis.
            SplashCoord xbase = seg->x0 - (seg->y0 * seg->dxdy);
            xx0 = xbase + ((SplashCoord)y0) * seg->dxdy;
            // the segment may not actually extend to the top and/or bottom edges
            if (xx0 < segXMin) {
                xx0 = segXMin;
            } else if (xx0 > segXMax) {
                xx0 = segXMax;
            }
            int x0 = splashFloor(xx0);

            for (y = y0; y <= y1; ++y) {
                xx1 = xbase + ((SplashCoord)(y + 1) * seg->dxdy);

                if (xx1 < segXMin) {
                    xx1 = segXMin;
                } else if (xx1 > segXMax) {
                    xx1 = segXMax;
                }
                int x1 = splashFloor(xx1);
                if (!addIntersection(segYMin, segYMax, y, x0, x1, count))
                    break;

                xx0 = xx1;
                x0 = x1;
            }
        }
    }
    for (auto &line : allIntersections) {
        std::sort(line.begin(), line.end(), [](const SplashIntersect i0, const SplashIntersect i1) { return i0.x0 < i1.x0; });
    }
}

inline bool SplashXPathScanner::addIntersection(double segYMin, double segYMax, int y, int x0, int x1, int count)
{
    SplashIntersect intersect;
    intersect.y = y;
    if (x0 < x1) {
        intersect.x0 = x0;
        intersect.x1 = x1;
    } else {
        intersect.x0 = x1;
        intersect.x1 = x0;
    }
    if (segYMin <= y && (SplashCoord)y < segYMax) {
        intersect.count = count;
    } else {
        intersect.count = 0;
    }

    auto &line = allIntersections[y - yMin];
#ifndef USE_BOOST_HEADERS
    if (line.empty()) {
        line.reserve(4);
    }
#endif
    line.push_back(intersect);

    return true;
}

void SplashXPathScanner::renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y, bool adjustVertLine) const
{
    int xx0, xx1, xx, xxMin, xxMax, yy, yyMax, interCount;
    size_t interIdx;
    unsigned char mask;
    SplashColorPtr p;

    memset(aaBuf->getDataPtr(), 0, aaBuf->getRowSize() * aaBuf->getHeight());
    xxMin = aaBuf->getWidth();
    xxMax = -1;
    if (yMin <= yMax) {
        yy = 0;
        yyMax = splashAASize - 1;
        // clamp start and end position
        if (yMin > splashAASize * y) {
            yy = yMin - splashAASize * y;
        }
        if (yyMax + splashAASize * y > yMax) {
            yyMax = yMax - splashAASize * y;
        }

        for (; yy <= yyMax; ++yy) {
            const auto &line = allIntersections[splashAASize * y + yy - yMin];
            interIdx = 0;
            interCount = 0;
            while (interIdx < line.size()) {
                xx0 = line[interIdx].x0;
                xx1 = line[interIdx].x1;
                interCount += line[interIdx].count;
                ++interIdx;
                while (interIdx < line.size() && (line[interIdx].x0 <= xx1 || (eo ? (interCount & 1) : (interCount != 0)))) {
                    if (line[interIdx].x1 > xx1) {
                        xx1 = line[interIdx].x1;
                    }
                    interCount += line[interIdx].count;
                    ++interIdx;
                }
                if (xx0 < 0) {
                    xx0 = 0;
                }
                ++xx1;
                if (xx1 > aaBuf->getWidth()) {
                    xx1 = aaBuf->getWidth();
                }
                // set [xx0, xx1) to 1
                if (xx0 < xx1) {
                    xx = xx0;
                    p = aaBuf->getDataPtr() + yy * aaBuf->getRowSize() + (xx >> 3);
                    if (xx & 7) {
                        mask = adjustVertLine ? 0xff : 0xff >> (xx & 7);
                        if (!adjustVertLine && (xx & ~7) == (xx1 & ~7)) {
                            mask &= (unsigned char)(0xff00 >> (xx1 & 7));
                        }
                        *p++ |= mask;
                        xx = (xx & ~7) + 8;
                    }
                    for (; xx + 7 < xx1; xx += 8) {
                        *p++ |= 0xff;
                    }
                    if (xx < xx1) {
                        *p |= adjustVertLine ? 0xff : (unsigned char)(0xff00 >> (xx1 & 7));
                    }
                }
                if (xx0 < xxMin) {
                    xxMin = xx0;
                }
                if (xx1 > xxMax) {
                    xxMax = xx1;
                }
            }
        }
    }
    if (xxMin > xxMax) {
        xxMin = xxMax;
    }
    *x0 = xxMin / splashAASize;
    *x1 = (xxMax - 1) / splashAASize;
}

void SplashXPathScanner::clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y) const
{
    int xx0, xx1, xx, yy, yyMin, yyMax, interCount;
    size_t interIdx;
    unsigned char mask;
    SplashColorPtr p;

    yyMin = 0;
    yyMax = splashAASize - 1;
    // clamp start and end position
    if (yMin > splashAASize * y) {
        yyMin = yMin - splashAASize * y;
    }
    if (yyMax + splashAASize * y > yMax) {
        yyMax = yMax - splashAASize * y;
    }
    for (yy = 0; yy < splashAASize; ++yy) {
        xx = *x0 * splashAASize;
        if (yy >= yyMin && yy <= yyMax) {
            const int intersectionIndex = splashAASize * y + yy - yMin;
            if (unlikely(intersectionIndex < 0 || (unsigned)intersectionIndex >= allIntersections.size()))
                break;
            const auto &line = allIntersections[intersectionIndex];
            interIdx = 0;
            interCount = 0;
            while (interIdx < line.size() && xx < (*x1 + 1) * splashAASize) {
                xx0 = line[interIdx].x0;
                xx1 = line[interIdx].x1;
                interCount += line[interIdx].count;
                ++interIdx;
                while (interIdx < line.size() && (line[interIdx].x0 <= xx1 || (eo ? (interCount & 1) : (interCount != 0)))) {
                    if (line[interIdx].x1 > xx1) {
                        xx1 = line[interIdx].x1;
                    }
                    interCount += line[interIdx].count;
                    ++interIdx;
                }
                if (xx0 > aaBuf->getWidth()) {
                    xx0 = aaBuf->getWidth();
                }
                // set [xx, xx0) to 0
                if (xx < xx0) {
                    p = aaBuf->getDataPtr() + yy * aaBuf->getRowSize() + (xx >> 3);
                    if (xx & 7) {
                        mask = (unsigned char)(0xff00 >> (xx & 7));
                        if ((xx & ~7) == (xx0 & ~7)) {
                            mask |= 0xff >> (xx0 & 7);
                        }
                        *p++ &= mask;
                        xx = (xx & ~7) + 8;
                    }
                    for (; xx + 7 < xx0; xx += 8) {
                        *p++ = 0x00;
                    }
                    if (xx < xx0) {
                        *p &= 0xff >> (xx0 & 7);
                    }
                }
                if (xx1 >= xx) {
                    xx = xx1 + 1;
                }
            }
        }
        xx0 = (*x1 + 1) * splashAASize;
        if (xx0 > aaBuf->getWidth())
            xx0 = aaBuf->getWidth();
        // set [xx, xx0) to 0
        if (xx < xx0 && xx >= 0) {
            p = aaBuf->getDataPtr() + yy * aaBuf->getRowSize() + (xx >> 3);
            if (xx & 7) {
                mask = (unsigned char)(0xff00 >> (xx & 7));
                if ((xx & ~7) == (xx0 & ~7)) {
                    mask &= 0xff >> (xx0 & 7);
                }
                *p++ &= mask;
                xx = (xx & ~7) + 8;
            }
            for (; xx + 7 < xx0; xx += 8) {
                *p++ = 0x00;
            }
            if (xx < xx0) {
                *p &= 0xff >> (xx0 & 7);
            }
        }
    }
}
