//========================================================================
//
// BBoxOutputDev.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2020 sgerwk <sgerwk@aol.com>
// Copyright 2022 Oliver Sander <oliver.sander@tu-dresden.de>
//
//========================================================================

#include <cmath>
#include <BBoxOutputDev.h>
#include <GfxFont.h>

#define writingModeHorizontal 0
#define writingModeVertical 1

BBoxOutputDev::BBoxOutputDev() : BBoxOutputDev(true, true, true) { }

BBoxOutputDev::BBoxOutputDev(bool textA, bool vectorA, bool rasterA) : BBoxOutputDev(textA, vectorA, rasterA, true) { }

BBoxOutputDev::BBoxOutputDev(bool textA, bool vectorA, bool rasterA, bool lwidthA)
{
    hasGraphics = false;
    text = textA;
    vector = vectorA;
    raster = rasterA;
    lwidth = lwidthA;
}

double BBoxOutputDev::getX1() const
{
    return bb.x1;
}

double BBoxOutputDev::getY1() const
{
    return bb.y1;
}

double BBoxOutputDev::getX2() const
{
    return bb.x2;
}

double BBoxOutputDev::getY2() const
{
    return bb.y2;
}

double BBoxOutputDev::getHasGraphics() const
{
    return hasGraphics;
}

void BBoxOutputDev::endPage() { }

void BBoxOutputDev::stroke(GfxState *state)
{
    updatePath(&bb, state->getPath(), state);
}

void BBoxOutputDev::fill(GfxState *state)
{
    updatePath(&bb, state->getPath(), state);
}

void BBoxOutputDev::eoFill(GfxState *state)
{
    updatePath(&bb, state->getPath(), state);
}

void BBoxOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg)
{
    updateImage(&bb, state);
}

void BBoxOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg)
{
    updateImage(&bb, state);
}

void BBoxOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, bool maskInvert, bool maskInterpolate)
{
    updateImage(&bb, state);
}

void BBoxOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap,
                                        bool maskInterpolate)
{
    updateImage(&bb, state);
}

void BBoxOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, const Unicode *u, int uLen)
{
    double leftent, rightent, ascent, descent;
    const double *fm, *fb;
    double fontSize, w, adjust;
    double fx, fy;

    if (!text) {
        return;
    }

    const GfxFont *const font = state->getFont().get();
    if (!font) {
        return;
    }

    if (code == (CharCode)0x20) {
        return;
    }

    fontSize = state->getFontSize();

    fb = font->getFontBBox();
    if (font->getWMode() == writingModeHorizontal) {
        leftent = 0;
        rightent = 0;
        ascent = font->getAscent();
        descent = font->getDescent();
    } else {
        if (fb[0] == 0 && fb[1] == 0 && fb[2] == 0 && fb[3] == 0) {
            leftent = -0.5;
            rightent = 0.5;
        } else {
            leftent = fb[1];
            rightent = fb[3];
        }
        ascent = 0;
        descent = 0;
    }

    if (font->getType() != fontType3) {
        adjust = 1;
    } else {
        // adjust font size for type3 fonts,
        // similar to TextPage::updateFont()
        w = ((Gfx8BitFont *)font)->getWidth(code);
        adjust = w / 0.5;
        fm = font->getFontMatrix();
        if (fm[0] != 0) {
            adjust *= fabs(fm[3] / fm[0]);
        }
    }

    ascent *= adjust * fontSize;
    descent *= adjust * fontSize;
    leftent *= adjust * fontSize;
    rightent *= adjust * fontSize;

    state->textTransformDelta(leftent, descent, &fx, &fy);
    updatePoint(&bb, fx + x, fy + y, state);

    state->textTransformDelta(rightent, ascent, &fx, &fy);
    updatePoint(&bb, fx + x, fy + y, state);

    state->textTransformDelta(leftent, descent, &fx, &fy);
    updatePoint(&bb, fx + x + dx, fy + y + dy, state);

    state->textTransformDelta(rightent, ascent, &fx, &fy);
    updatePoint(&bb, fx + x + dx, fy + y + dy, state);
}

/* update the bounding box with a new point */
void BBoxOutputDev::updatePoint(PDFRectangle *bbA, double x, double y, const GfxState *state)
{
    Matrix o = { 1, 0, 0, 1, 0, 0 };
    double tx, ty;
    double xMin, yMin, xMax, yMax;

    state->getClipBBox(&xMin, &yMin, &xMax, &yMax);

    o.scale(1, -1);
    o.translate(0, -state->getPageHeight());

    state->transform(x, y, &tx, &ty);
    tx = tx < xMin ? xMin : tx > xMax ? xMax : tx;
    ty = ty < yMin ? yMin : ty > yMax ? yMax : ty;
    o.transform(tx, ty, &x, &y);

    if (!hasGraphics || bbA->x1 > x) {
        bbA->x1 = x;
    }
    if (!hasGraphics || bbA->y1 > y) {
        bbA->y1 = y;
    }
    if (!hasGraphics || bbA->x2 < x) {
        bbA->x2 = x;
    }
    if (!hasGraphics || bbA->y2 < y) {
        bbA->y2 = y;
    }
    hasGraphics = true;
}

/* update the bounding box with a new path */
void BBoxOutputDev::updatePath(PDFRectangle *bbA, const GfxPath *path, const GfxState *state)
{
    int i, j;
    const GfxSubpath *subpath;
    double x, y;
    double w;
    if (!vector) {
        return;
    }
    w = lwidth ? state->getLineWidth() : 0;
    for (i = 0; i < path->getNumSubpaths(); i++) {
        subpath = path->getSubpath(i);
        for (j = 0; j < subpath->getNumPoints(); j++) {
            x = subpath->getX(j);
            y = subpath->getY(j);
            updatePoint(bbA, x - w / 2, y - w / 2, state);
            updatePoint(bbA, x + w / 2, y + w / 2, state);
        }
    }
}

/* update the bounding box with a new image */
void BBoxOutputDev::updateImage(PDFRectangle *bbA, const GfxState *state)
{
    if (!raster) {
        return;
    }
    updatePoint(bbA, 0, 1, state);
    updatePoint(bbA, 1, 0, state);
}
