// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sfnt

import (
	"golang.org/x/image/math/fixed"
)

// Flags for simple (non-compound) glyphs.
//
// See https://www.microsoft.com/typography/OTSPEC/glyf.htm
const (
	flagOnCurve      = 1 << 0 // 0x0001
	flagXShortVector = 1 << 1 // 0x0002
	flagYShortVector = 1 << 2 // 0x0004
	flagRepeat       = 1 << 3 // 0x0008

	// The same flag bits are overloaded to have two meanings, dependent on the
	// value of the flag{X,Y}ShortVector bits.
	flagPositiveXShortVector = 1 << 4 // 0x0010
	flagThisXIsSame          = 1 << 4 // 0x0010
	flagPositiveYShortVector = 1 << 5 // 0x0020
	flagThisYIsSame          = 1 << 5 // 0x0020
)

// Flags for compound glyphs.
//
// See https://www.microsoft.com/typography/OTSPEC/glyf.htm
const (
	flagArg1And2AreWords        = 1 << 0  // 0x0001
	flagArgsAreXYValues         = 1 << 1  // 0x0002
	flagRoundXYToGrid           = 1 << 2  // 0x0004
	flagWeHaveAScale            = 1 << 3  // 0x0008
	flagReserved4               = 1 << 4  // 0x0010
	flagMoreComponents          = 1 << 5  // 0x0020
	flagWeHaveAnXAndYScale      = 1 << 6  // 0x0040
	flagWeHaveATwoByTwo         = 1 << 7  // 0x0080
	flagWeHaveInstructions      = 1 << 8  // 0x0100
	flagUseMyMetrics            = 1 << 9  // 0x0200
	flagOverlapCompound         = 1 << 10 // 0x0400
	flagScaledComponentOffset   = 1 << 11 // 0x0800
	flagUnscaledComponentOffset = 1 << 12 // 0x1000
)

func midPoint(p, q fixed.Point26_6) fixed.Point26_6 {
	return fixed.Point26_6{
		X: (p.X + q.X) / 2,
		Y: (p.Y + q.Y) / 2,
	}
}

func parseLoca(src *source, loca table, glyfOffset uint32, indexToLocFormat bool, numGlyphs int) (locations []uint32, err error) {
	if indexToLocFormat {
		if loca.length != 4*uint32(numGlyphs+1) {
			return nil, errInvalidLocaTable
		}
	} else {
		if loca.length != 2*uint32(numGlyphs+1) {
			return nil, errInvalidLocaTable
		}
	}

	locations = make([]uint32, numGlyphs+1)
	buf, err := src.view(nil, int(loca.offset), int(loca.length))
	if err != nil {
		return nil, err
	}

	if indexToLocFormat {
		for i := range locations {
			locations[i] = 1*uint32(u32(buf[4*i:])) + glyfOffset
		}
	} else {
		for i := range locations {
			locations[i] = 2*uint32(u16(buf[2*i:])) + glyfOffset
		}
	}
	return locations, err
}

// https://www.microsoft.com/typography/OTSPEC/glyf.htm says that "Each
// glyph begins with the following [10 byte] header".
const glyfHeaderLen = 10

func loadGlyf(f *Font, b *Buffer, x GlyphIndex, stackBottom, recursionDepth uint32) error {
	data, _, _, err := f.viewGlyphData(b, x)
	if err != nil {
		return err
	}
	if len(data) == 0 {
		return nil
	}
	if len(data) < glyfHeaderLen {
		return errInvalidGlyphData
	}
	index := glyfHeaderLen

	numContours, numPoints := int16(u16(data)), 0
	switch {
	case numContours == -1:
		// We have a compound glyph. No-op.
	case numContours == 0:
		return nil
	case numContours > 0:
		// We have a simple (non-compound) glyph.
		index += 2 * int(numContours)
		if index > len(data) {
			return errInvalidGlyphData
		}
		// The +1 for numPoints is because the value in the file format is
		// inclusive, but Go's slice[:index] semantics are exclusive.
		numPoints = 1 + int(u16(data[index-2:]))
	default:
		return errInvalidGlyphData
	}

	if numContours < 0 {
		return loadCompoundGlyf(f, b, data[glyfHeaderLen:], stackBottom, recursionDepth)
	}

	// Skip the hinting instructions.
	index += 2
	if index > len(data) {
		return errInvalidGlyphData
	}
	hintsLength := int(u16(data[index-2:]))
	index += hintsLength
	if index > len(data) {
		return errInvalidGlyphData
	}

	// For simple (non-compound) glyphs, the remainder of the glyf data
	// consists of (flags, x, y) points: the Bézier curve segments. These are
	// stored in columns (all the flags first, then all the x coordinates, then
	// all the y coordinates), not rows, as it compresses better.
	//
	// Decoding those points in row order involves two passes. The first pass
	// determines the indexes (relative to the data slice) of where the flags,
	// the x coordinates and the y coordinates each start.
	flagIndex := int32(index)
	xIndex, yIndex, ok := findXYIndexes(data, index, numPoints)
	if !ok {
		return errInvalidGlyphData
	}

	// The second pass decodes each (flags, x, y) tuple in row order.
	g := glyfIter{
		data:      data,
		flagIndex: flagIndex,
		xIndex:    xIndex,
		yIndex:    yIndex,
		endIndex:  glyfHeaderLen,
		// The -1 is because the contour-end index in the file format is
		// inclusive, but Go's slice[:index] semantics are exclusive.
		prevEnd:     -1,
		numContours: int32(numContours),
	}
	for g.nextContour() {
		for g.nextSegment() {
			b.segments = append(b.segments, g.seg)
		}
	}
	return g.err
}

func findXYIndexes(data []byte, index, numPoints int) (xIndex, yIndex int32, ok bool) {
	xDataLen := 0
	yDataLen := 0
	for i := 0; ; {
		if i > numPoints {
			return 0, 0, false
		}
		if i == numPoints {
			break
		}

		repeatCount := 1
		if index >= len(data) {
			return 0, 0, false
		}
		flag := data[index]
		index++
		if flag&flagRepeat != 0 {
			if index >= len(data) {
				return 0, 0, false
			}
			repeatCount += int(data[index])
			index++
		}

		xSize := 0
		if flag&flagXShortVector != 0 {
			xSize = 1
		} else if flag&flagThisXIsSame == 0 {
			xSize = 2
		}
		xDataLen += xSize * repeatCount

		ySize := 0
		if flag&flagYShortVector != 0 {
			ySize = 1
		} else if flag&flagThisYIsSame == 0 {
			ySize = 2
		}
		yDataLen += ySize * repeatCount

		i += repeatCount
	}
	if index+xDataLen+yDataLen > len(data) {
		return 0, 0, false
	}
	return int32(index), int32(index + xDataLen), true
}

func loadCompoundGlyf(f *Font, b *Buffer, data []byte, stackBottom, recursionDepth uint32) error {
	if recursionDepth++; recursionDepth == maxCompoundRecursionDepth {
		return errUnsupportedCompoundGlyph
	}

	// Read and process the compound glyph's components. They are two separate
	// for loops, since reading parses the elements of the data slice, and
	// processing can overwrite the backing array.

	stackTop := stackBottom
	for {
		if stackTop >= maxCompoundStackSize {
			return errUnsupportedCompoundGlyph
		}
		elem := &b.compoundStack[stackTop]
		stackTop++

		if len(data) < 4 {
			return errInvalidGlyphData
		}
		flags := u16(data)
		elem.glyphIndex = GlyphIndex(u16(data[2:]))
		if flags&flagArg1And2AreWords == 0 {
			if len(data) < 6 {
				return errInvalidGlyphData
			}
			elem.dx = int16(int8(data[4]))
			elem.dy = int16(int8(data[5]))
			data = data[6:]
		} else {
			if len(data) < 8 {
				return errInvalidGlyphData
			}
			elem.dx = int16(u16(data[4:]))
			elem.dy = int16(u16(data[6:]))
			data = data[8:]
		}

		if flags&flagArgsAreXYValues == 0 {
			return errUnsupportedCompoundGlyph
		}
		elem.hasTransform = flags&(flagWeHaveAScale|flagWeHaveAnXAndYScale|flagWeHaveATwoByTwo) != 0
		if elem.hasTransform {
			switch {
			case flags&flagWeHaveAScale != 0:
				if len(data) < 2 {
					return errInvalidGlyphData
				}
				elem.transformXX = int16(u16(data))
				elem.transformXY = 0
				elem.transformYX = 0
				elem.transformYY = elem.transformXX
				data = data[2:]
			case flags&flagWeHaveAnXAndYScale != 0:
				if len(data) < 4 {
					return errInvalidGlyphData
				}
				elem.transformXX = int16(u16(data[0:]))
				elem.transformXY = 0
				elem.transformYX = 0
				elem.transformYY = int16(u16(data[2:]))
				data = data[4:]
			case flags&flagWeHaveATwoByTwo != 0:
				if len(data) < 8 {
					return errInvalidGlyphData
				}
				elem.transformXX = int16(u16(data[0:]))
				elem.transformXY = int16(u16(data[2:]))
				elem.transformYX = int16(u16(data[4:]))
				elem.transformYY = int16(u16(data[6:]))
				data = data[8:]
			}
		}

		if flags&flagMoreComponents == 0 {
			break
		}
	}

	// To support hinting, we'd have to save the remaining bytes in data here
	// and interpret them after the for loop below, since that for loop's
	// loadGlyf calls can overwrite the backing array.

	for i := stackBottom; i < stackTop; i++ {
		elem := &b.compoundStack[i]
		base := len(b.segments)
		if err := loadGlyf(f, b, elem.glyphIndex, stackTop, recursionDepth); err != nil {
			return err
		}
		dx, dy := fixed.Int26_6(elem.dx), fixed.Int26_6(elem.dy)
		segs := b.segments[base:]
		if elem.hasTransform {
			txx := elem.transformXX
			txy := elem.transformXY
			tyx := elem.transformYX
			tyy := elem.transformYY
			for j := range segs {
				transformArgs(&segs[j].Args, txx, txy, tyx, tyy, dx, dy)
			}
		} else {
			for j := range segs {
				translateArgs(&segs[j].Args, dx, dy)
			}
		}
	}

	return nil
}

type glyfIter struct {
	data []byte
	err  error

	// Various indices into the data slice. See the "Decoding those points in
	// row order" comment above.
	flagIndex int32
	xIndex    int32
	yIndex    int32

	// endIndex points to the uint16 that is the inclusive point index of the
	// current contour's end. prevEnd is the previous contour's end.
	endIndex int32
	prevEnd  int32

	// c and p count the current contour and point, up to numContours and
	// numPoints.
	c, numContours int32
	p, nPoints     int32

	// The next two groups of fields track points and segments. Points are what
	// the underlying file format provides. Bézier curve segments are what the
	// rasterizer consumes.
	//
	// Points are either on-curve or off-curve. Two consecutive on-curve points
	// define a linear curve segment between them. N off-curve points between
	// on-curve points define N quadratic curve segments. The TrueType glyf
	// format does not use cubic curves. If N is greater than 1, some of these
	// segment end points are implicit, the midpoint of two off-curve points.
	// Given the points A, B1, B2, ..., BN, C, where A and C are on-curve and
	// all the Bs are off-curve, the segments are:
	//
	//	- A,                  B1, midpoint(B1, B2)
	//	- midpoint(B1, B2),   B2, midpoint(B2, B3)
	//	- midpoint(B2, B3),   B3, midpoint(B3, B4)
	//	- ...
	//	- midpoint(BN-1, BN), BN, C
	//
	// Note that the sequence of Bs may wrap around from the last point in the
	// glyf data to the first. A and C may also be the same point (the only
	// explicit on-curve point), or there may be no explicit on-curve points at
	// all (but still implicit ones between explicit off-curve points).

	// Points.
	x, y    int16
	on      bool
	flag    uint8
	repeats uint8

	// Segments.
	closing            bool
	closed             bool
	firstOnCurveValid  bool
	firstOffCurveValid bool
	lastOffCurveValid  bool
	firstOnCurve       fixed.Point26_6
	firstOffCurve      fixed.Point26_6
	lastOffCurve       fixed.Point26_6
	seg                Segment
}

func (g *glyfIter) nextContour() (ok bool) {
	if g.c == g.numContours {
		return false
	}
	g.c++

	end := int32(u16(g.data[g.endIndex:]))
	g.endIndex += 2
	if end <= g.prevEnd {
		g.err = errInvalidGlyphData
		return false
	}
	g.nPoints = end - g.prevEnd
	g.p = 0
	g.prevEnd = end

	g.closing = false
	g.closed = false
	g.firstOnCurveValid = false
	g.firstOffCurveValid = false
	g.lastOffCurveValid = false

	return true
}

func (g *glyfIter) close() {
	switch {
	case !g.firstOffCurveValid && !g.lastOffCurveValid:
		g.closed = true
		g.seg = Segment{
			Op:   SegmentOpLineTo,
			Args: [3]fixed.Point26_6{g.firstOnCurve},
		}
	case !g.firstOffCurveValid && g.lastOffCurveValid:
		g.closed = true
		g.seg = Segment{
			Op:   SegmentOpQuadTo,
			Args: [3]fixed.Point26_6{g.lastOffCurve, g.firstOnCurve},
		}
	case g.firstOffCurveValid && !g.lastOffCurveValid:
		g.closed = true
		g.seg = Segment{
			Op:   SegmentOpQuadTo,
			Args: [3]fixed.Point26_6{g.firstOffCurve, g.firstOnCurve},
		}
	case g.firstOffCurveValid && g.lastOffCurveValid:
		g.lastOffCurveValid = false
		g.seg = Segment{
			Op: SegmentOpQuadTo,
			Args: [3]fixed.Point26_6{
				g.lastOffCurve,
				midPoint(g.lastOffCurve, g.firstOffCurve),
			},
		}
	}
}

func (g *glyfIter) nextSegment() (ok bool) {
	for !g.closed {
		if g.closing || !g.nextPoint() {
			g.closing = true
			g.close()
			return true
		}

		// Convert the tuple (g.x, g.y) to a fixed.Point26_6, since the latter
		// is what's held in a Segment. The input (g.x, g.y) is a pair of int16
		// values, measured in font units, since that is what the underlying
		// format provides. The output is a pair of fixed.Int26_6 values. A
		// fixed.Int26_6 usually represents a 26.6 fixed number of pixels, but
		// this here is just a straight numerical conversion, with no scaling
		// factor. A later step scales the Segment.Args values by such a factor
		// to convert e.g. 1792 font units to 10.5 pixels at 2048 font units
		// per em and 12 ppem (pixels per em).
		p := fixed.Point26_6{
			X: fixed.Int26_6(g.x),
			Y: fixed.Int26_6(g.y),
		}

		if !g.firstOnCurveValid {
			if g.on {
				g.firstOnCurve = p
				g.firstOnCurveValid = true
				g.seg = Segment{
					Op:   SegmentOpMoveTo,
					Args: [3]fixed.Point26_6{p},
				}
				return true
			} else if !g.firstOffCurveValid {
				g.firstOffCurve = p
				g.firstOffCurveValid = true
				continue
			} else {
				g.firstOnCurve = midPoint(g.firstOffCurve, p)
				g.firstOnCurveValid = true
				g.lastOffCurve = p
				g.lastOffCurveValid = true
				g.seg = Segment{
					Op:   SegmentOpMoveTo,
					Args: [3]fixed.Point26_6{g.firstOnCurve},
				}
				return true
			}

		} else if !g.lastOffCurveValid {
			if !g.on {
				g.lastOffCurve = p
				g.lastOffCurveValid = true
				continue
			} else {
				g.seg = Segment{
					Op:   SegmentOpLineTo,
					Args: [3]fixed.Point26_6{p},
				}
				return true
			}

		} else {
			if !g.on {
				g.seg = Segment{
					Op: SegmentOpQuadTo,
					Args: [3]fixed.Point26_6{
						g.lastOffCurve,
						midPoint(g.lastOffCurve, p),
					},
				}
				g.lastOffCurve = p
				g.lastOffCurveValid = true
				return true
			} else {
				g.seg = Segment{
					Op:   SegmentOpQuadTo,
					Args: [3]fixed.Point26_6{g.lastOffCurve, p},
				}
				g.lastOffCurveValid = false
				return true
			}
		}
	}
	return false
}

func (g *glyfIter) nextPoint() (ok bool) {
	if g.p == g.nPoints {
		return false
	}
	g.p++

	if g.repeats > 0 {
		g.repeats--
	} else {
		g.flag = g.data[g.flagIndex]
		g.flagIndex++
		if g.flag&flagRepeat != 0 {
			g.repeats = g.data[g.flagIndex]
			g.flagIndex++
		}
	}

	if g.flag&flagXShortVector != 0 {
		if g.flag&flagPositiveXShortVector != 0 {
			g.x += int16(g.data[g.xIndex])
		} else {
			g.x -= int16(g.data[g.xIndex])
		}
		g.xIndex += 1
	} else if g.flag&flagThisXIsSame == 0 {
		g.x += int16(u16(g.data[g.xIndex:]))
		g.xIndex += 2
	}

	if g.flag&flagYShortVector != 0 {
		if g.flag&flagPositiveYShortVector != 0 {
			g.y += int16(g.data[g.yIndex])
		} else {
			g.y -= int16(g.data[g.yIndex])
		}
		g.yIndex += 1
	} else if g.flag&flagThisYIsSame == 0 {
		g.y += int16(u16(g.data[g.yIndex:]))
		g.yIndex += 2
	}

	g.on = g.flag&flagOnCurve != 0
	return true
}
