chore: nuke vendor directory
This commit is contained in:
parent
d16645c952
commit
0e9b92dbdf
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,3 +7,6 @@ matterbridge.toml
|
|||||||
|
|
||||||
# Exclude IDE Files
|
# Exclude IDE Files
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# Exclude Vendor
|
||||||
|
/vendor
|
27
vendor/filippo.io/edwards25519/LICENSE
generated
vendored
27
vendor/filippo.io/edwards25519/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
14
vendor/filippo.io/edwards25519/README.md
generated
vendored
14
vendor/filippo.io/edwards25519/README.md
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
# filippo.io/edwards25519
|
|
||||||
|
|
||||||
```
|
|
||||||
import "filippo.io/edwards25519"
|
|
||||||
```
|
|
||||||
|
|
||||||
This library implements the edwards25519 elliptic curve, exposing the necessary APIs to build a wide array of higher-level primitives.
|
|
||||||
Read the docs at [pkg.go.dev/filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519).
|
|
||||||
|
|
||||||
The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. It now tracks the upstream codebase and extends it with additional functionality.
|
|
||||||
|
|
||||||
Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative.
|
|
||||||
|
|
||||||
Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements.
|
|
20
vendor/filippo.io/edwards25519/doc.go
generated
vendored
20
vendor/filippo.io/edwards25519/doc.go
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
// Copyright (c) 2021 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 edwards25519 implements group logic for the twisted Edwards curve
|
|
||||||
//
|
|
||||||
// -x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2
|
|
||||||
//
|
|
||||||
// This is better known as the Edwards curve equivalent to Curve25519, and is
|
|
||||||
// the curve used by the Ed25519 signature scheme.
|
|
||||||
//
|
|
||||||
// Most users don't need this package, and should instead use crypto/ed25519 for
|
|
||||||
// signatures, golang.org/x/crypto/curve25519 for Diffie-Hellman, or
|
|
||||||
// github.com/gtank/ristretto255 for prime order group logic.
|
|
||||||
//
|
|
||||||
// However, developers who do need to interact with low-level edwards25519
|
|
||||||
// operations can use this package, which is an extended version of
|
|
||||||
// crypto/ed25519/internal/edwards25519 from the standard library repackaged as
|
|
||||||
// an importable module.
|
|
||||||
package edwards25519
|
|
428
vendor/filippo.io/edwards25519/edwards25519.go
generated
vendored
428
vendor/filippo.io/edwards25519/edwards25519.go
generated
vendored
@ -1,428 +0,0 @@
|
|||||||
// Copyright (c) 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 edwards25519
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"filippo.io/edwards25519/field"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Point types.
|
|
||||||
|
|
||||||
type projP1xP1 struct {
|
|
||||||
X, Y, Z, T field.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
type projP2 struct {
|
|
||||||
X, Y, Z field.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Point represents a point on the edwards25519 curve.
|
|
||||||
//
|
|
||||||
// This type works similarly to math/big.Int, and all arguments and receivers
|
|
||||||
// are allowed to alias.
|
|
||||||
//
|
|
||||||
// The zero value is NOT valid, and it may be used only as a receiver.
|
|
||||||
type Point struct {
|
|
||||||
// The point is internally represented in extended coordinates (X, Y, Z, T)
|
|
||||||
// where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522.
|
|
||||||
x, y, z, t field.Element
|
|
||||||
|
|
||||||
// Make the type not comparable (i.e. used with == or as a map key), as
|
|
||||||
// equivalent points can be represented by different Go values.
|
|
||||||
_ incomparable
|
|
||||||
}
|
|
||||||
|
|
||||||
type incomparable [0]func()
|
|
||||||
|
|
||||||
func checkInitialized(points ...*Point) {
|
|
||||||
for _, p := range points {
|
|
||||||
if p.x == (field.Element{}) && p.y == (field.Element{}) {
|
|
||||||
panic("edwards25519: use of uninitialized Point")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type projCached struct {
|
|
||||||
YplusX, YminusX, Z, T2d field.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
type affineCached struct {
|
|
||||||
YplusX, YminusX, T2d field.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructors.
|
|
||||||
|
|
||||||
func (v *projP2) Zero() *projP2 {
|
|
||||||
v.X.Zero()
|
|
||||||
v.Y.One()
|
|
||||||
v.Z.One()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// identity is the point at infinity.
|
|
||||||
var identity, _ = new(Point).SetBytes([]byte{
|
|
||||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
|
|
||||||
|
|
||||||
// NewIdentityPoint returns a new Point set to the identity.
|
|
||||||
func NewIdentityPoint() *Point {
|
|
||||||
return new(Point).Set(identity)
|
|
||||||
}
|
|
||||||
|
|
||||||
// generator is the canonical curve basepoint. See TestGenerator for the
|
|
||||||
// correspondence of this encoding with the values in RFC 8032.
|
|
||||||
var generator, _ = new(Point).SetBytes([]byte{
|
|
||||||
0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})
|
|
||||||
|
|
||||||
// NewGeneratorPoint returns a new Point set to the canonical generator.
|
|
||||||
func NewGeneratorPoint() *Point {
|
|
||||||
return new(Point).Set(generator)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *projCached) Zero() *projCached {
|
|
||||||
v.YplusX.One()
|
|
||||||
v.YminusX.One()
|
|
||||||
v.Z.One()
|
|
||||||
v.T2d.Zero()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *affineCached) Zero() *affineCached {
|
|
||||||
v.YplusX.One()
|
|
||||||
v.YminusX.One()
|
|
||||||
v.T2d.Zero()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignments.
|
|
||||||
|
|
||||||
// Set sets v = u, and returns v.
|
|
||||||
func (v *Point) Set(u *Point) *Point {
|
|
||||||
*v = *u
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encoding.
|
|
||||||
|
|
||||||
// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
|
|
||||||
// Section 5.1.2.
|
|
||||||
func (v *Point) Bytes() []byte {
|
|
||||||
// This function is outlined to make the allocations inline in the caller
|
|
||||||
// rather than happen on the heap.
|
|
||||||
var buf [32]byte
|
|
||||||
return v.bytes(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Point) bytes(buf *[32]byte) []byte {
|
|
||||||
checkInitialized(v)
|
|
||||||
|
|
||||||
var zInv, x, y field.Element
|
|
||||||
zInv.Invert(&v.z) // zInv = 1 / Z
|
|
||||||
x.Multiply(&v.x, &zInv) // x = X / Z
|
|
||||||
y.Multiply(&v.y, &zInv) // y = Y / Z
|
|
||||||
|
|
||||||
out := copyFieldElement(buf, &y)
|
|
||||||
out[31] |= byte(x.IsNegative() << 7)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
var feOne = new(field.Element).One()
|
|
||||||
|
|
||||||
// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not
|
|
||||||
// represent a valid point on the curve, SetBytes returns nil and an error and
|
|
||||||
// the receiver is unchanged. Otherwise, SetBytes returns v.
|
|
||||||
//
|
|
||||||
// Note that SetBytes accepts all non-canonical encodings of valid points.
|
|
||||||
// That is, it follows decoding rules that match most implementations in
|
|
||||||
// the ecosystem rather than RFC 8032.
|
|
||||||
func (v *Point) SetBytes(x []byte) (*Point, error) {
|
|
||||||
// Specifically, the non-canonical encodings that are accepted are
|
|
||||||
// 1) the ones where the field element is not reduced (see the
|
|
||||||
// (*field.Element).SetBytes docs) and
|
|
||||||
// 2) the ones where the x-coordinate is zero and the sign bit is set.
|
|
||||||
//
|
|
||||||
// This is consistent with crypto/ed25519/internal/edwards25519. Read more
|
|
||||||
// at https://hdevalence.ca/blog/2020-10-04-its-25519am, specifically the
|
|
||||||
// "Canonical A, R" section.
|
|
||||||
|
|
||||||
y, err := new(field.Element).SetBytes(x)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("edwards25519: invalid point encoding length")
|
|
||||||
}
|
|
||||||
|
|
||||||
// -x² + y² = 1 + dx²y²
|
|
||||||
// x² + dx²y² = x²(dy² + 1) = y² - 1
|
|
||||||
// x² = (y² - 1) / (dy² + 1)
|
|
||||||
|
|
||||||
// u = y² - 1
|
|
||||||
y2 := new(field.Element).Square(y)
|
|
||||||
u := new(field.Element).Subtract(y2, feOne)
|
|
||||||
|
|
||||||
// v = dy² + 1
|
|
||||||
vv := new(field.Element).Multiply(y2, d)
|
|
||||||
vv = vv.Add(vv, feOne)
|
|
||||||
|
|
||||||
// x = +√(u/v)
|
|
||||||
xx, wasSquare := new(field.Element).SqrtRatio(u, vv)
|
|
||||||
if wasSquare == 0 {
|
|
||||||
return nil, errors.New("edwards25519: invalid point encoding")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select the negative square root if the sign bit is set.
|
|
||||||
xxNeg := new(field.Element).Negate(xx)
|
|
||||||
xx = xx.Select(xxNeg, xx, int(x[31]>>7))
|
|
||||||
|
|
||||||
v.x.Set(xx)
|
|
||||||
v.y.Set(y)
|
|
||||||
v.z.One()
|
|
||||||
v.t.Multiply(xx, y) // xy = T / Z
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyFieldElement(buf *[32]byte, v *field.Element) []byte {
|
|
||||||
copy(buf[:], v.Bytes())
|
|
||||||
return buf[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conversions.
|
|
||||||
|
|
||||||
func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 {
|
|
||||||
v.X.Multiply(&p.X, &p.T)
|
|
||||||
v.Y.Multiply(&p.Y, &p.Z)
|
|
||||||
v.Z.Multiply(&p.Z, &p.T)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *projP2) FromP3(p *Point) *projP2 {
|
|
||||||
v.X.Set(&p.x)
|
|
||||||
v.Y.Set(&p.y)
|
|
||||||
v.Z.Set(&p.z)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Point) fromP1xP1(p *projP1xP1) *Point {
|
|
||||||
v.x.Multiply(&p.X, &p.T)
|
|
||||||
v.y.Multiply(&p.Y, &p.Z)
|
|
||||||
v.z.Multiply(&p.Z, &p.T)
|
|
||||||
v.t.Multiply(&p.X, &p.Y)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Point) fromP2(p *projP2) *Point {
|
|
||||||
v.x.Multiply(&p.X, &p.Z)
|
|
||||||
v.y.Multiply(&p.Y, &p.Z)
|
|
||||||
v.z.Square(&p.Z)
|
|
||||||
v.t.Multiply(&p.X, &p.Y)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// d is a constant in the curve equation.
|
|
||||||
var d, _ = new(field.Element).SetBytes([]byte{
|
|
||||||
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
|
|
||||||
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
|
|
||||||
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
|
|
||||||
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})
|
|
||||||
var d2 = new(field.Element).Add(d, d)
|
|
||||||
|
|
||||||
func (v *projCached) FromP3(p *Point) *projCached {
|
|
||||||
v.YplusX.Add(&p.y, &p.x)
|
|
||||||
v.YminusX.Subtract(&p.y, &p.x)
|
|
||||||
v.Z.Set(&p.z)
|
|
||||||
v.T2d.Multiply(&p.t, d2)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *affineCached) FromP3(p *Point) *affineCached {
|
|
||||||
v.YplusX.Add(&p.y, &p.x)
|
|
||||||
v.YminusX.Subtract(&p.y, &p.x)
|
|
||||||
v.T2d.Multiply(&p.t, d2)
|
|
||||||
|
|
||||||
var invZ field.Element
|
|
||||||
invZ.Invert(&p.z)
|
|
||||||
v.YplusX.Multiply(&v.YplusX, &invZ)
|
|
||||||
v.YminusX.Multiply(&v.YminusX, &invZ)
|
|
||||||
v.T2d.Multiply(&v.T2d, &invZ)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Re)addition and subtraction.
|
|
||||||
|
|
||||||
// Add sets v = p + q, and returns v.
|
|
||||||
func (v *Point) Add(p, q *Point) *Point {
|
|
||||||
checkInitialized(p, q)
|
|
||||||
qCached := new(projCached).FromP3(q)
|
|
||||||
result := new(projP1xP1).Add(p, qCached)
|
|
||||||
return v.fromP1xP1(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtract sets v = p - q, and returns v.
|
|
||||||
func (v *Point) Subtract(p, q *Point) *Point {
|
|
||||||
checkInitialized(p, q)
|
|
||||||
qCached := new(projCached).FromP3(q)
|
|
||||||
result := new(projP1xP1).Sub(p, qCached)
|
|
||||||
return v.fromP1xP1(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 {
|
|
||||||
var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
|
|
||||||
|
|
||||||
YplusX.Add(&p.y, &p.x)
|
|
||||||
YminusX.Subtract(&p.y, &p.x)
|
|
||||||
|
|
||||||
PP.Multiply(&YplusX, &q.YplusX)
|
|
||||||
MM.Multiply(&YminusX, &q.YminusX)
|
|
||||||
TT2d.Multiply(&p.t, &q.T2d)
|
|
||||||
ZZ2.Multiply(&p.z, &q.Z)
|
|
||||||
|
|
||||||
ZZ2.Add(&ZZ2, &ZZ2)
|
|
||||||
|
|
||||||
v.X.Subtract(&PP, &MM)
|
|
||||||
v.Y.Add(&PP, &MM)
|
|
||||||
v.Z.Add(&ZZ2, &TT2d)
|
|
||||||
v.T.Subtract(&ZZ2, &TT2d)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 {
|
|
||||||
var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
|
|
||||||
|
|
||||||
YplusX.Add(&p.y, &p.x)
|
|
||||||
YminusX.Subtract(&p.y, &p.x)
|
|
||||||
|
|
||||||
PP.Multiply(&YplusX, &q.YminusX) // flipped sign
|
|
||||||
MM.Multiply(&YminusX, &q.YplusX) // flipped sign
|
|
||||||
TT2d.Multiply(&p.t, &q.T2d)
|
|
||||||
ZZ2.Multiply(&p.z, &q.Z)
|
|
||||||
|
|
||||||
ZZ2.Add(&ZZ2, &ZZ2)
|
|
||||||
|
|
||||||
v.X.Subtract(&PP, &MM)
|
|
||||||
v.Y.Add(&PP, &MM)
|
|
||||||
v.Z.Subtract(&ZZ2, &TT2d) // flipped sign
|
|
||||||
v.T.Add(&ZZ2, &TT2d) // flipped sign
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 {
|
|
||||||
var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
|
|
||||||
|
|
||||||
YplusX.Add(&p.y, &p.x)
|
|
||||||
YminusX.Subtract(&p.y, &p.x)
|
|
||||||
|
|
||||||
PP.Multiply(&YplusX, &q.YplusX)
|
|
||||||
MM.Multiply(&YminusX, &q.YminusX)
|
|
||||||
TT2d.Multiply(&p.t, &q.T2d)
|
|
||||||
|
|
||||||
Z2.Add(&p.z, &p.z)
|
|
||||||
|
|
||||||
v.X.Subtract(&PP, &MM)
|
|
||||||
v.Y.Add(&PP, &MM)
|
|
||||||
v.Z.Add(&Z2, &TT2d)
|
|
||||||
v.T.Subtract(&Z2, &TT2d)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 {
|
|
||||||
var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
|
|
||||||
|
|
||||||
YplusX.Add(&p.y, &p.x)
|
|
||||||
YminusX.Subtract(&p.y, &p.x)
|
|
||||||
|
|
||||||
PP.Multiply(&YplusX, &q.YminusX) // flipped sign
|
|
||||||
MM.Multiply(&YminusX, &q.YplusX) // flipped sign
|
|
||||||
TT2d.Multiply(&p.t, &q.T2d)
|
|
||||||
|
|
||||||
Z2.Add(&p.z, &p.z)
|
|
||||||
|
|
||||||
v.X.Subtract(&PP, &MM)
|
|
||||||
v.Y.Add(&PP, &MM)
|
|
||||||
v.Z.Subtract(&Z2, &TT2d) // flipped sign
|
|
||||||
v.T.Add(&Z2, &TT2d) // flipped sign
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Doubling.
|
|
||||||
|
|
||||||
func (v *projP1xP1) Double(p *projP2) *projP1xP1 {
|
|
||||||
var XX, YY, ZZ2, XplusYsq field.Element
|
|
||||||
|
|
||||||
XX.Square(&p.X)
|
|
||||||
YY.Square(&p.Y)
|
|
||||||
ZZ2.Square(&p.Z)
|
|
||||||
ZZ2.Add(&ZZ2, &ZZ2)
|
|
||||||
XplusYsq.Add(&p.X, &p.Y)
|
|
||||||
XplusYsq.Square(&XplusYsq)
|
|
||||||
|
|
||||||
v.Y.Add(&YY, &XX)
|
|
||||||
v.Z.Subtract(&YY, &XX)
|
|
||||||
|
|
||||||
v.X.Subtract(&XplusYsq, &v.Y)
|
|
||||||
v.T.Subtract(&ZZ2, &v.Z)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Negation.
|
|
||||||
|
|
||||||
// Negate sets v = -p, and returns v.
|
|
||||||
func (v *Point) Negate(p *Point) *Point {
|
|
||||||
checkInitialized(p)
|
|
||||||
v.x.Negate(&p.x)
|
|
||||||
v.y.Set(&p.y)
|
|
||||||
v.z.Set(&p.z)
|
|
||||||
v.t.Negate(&p.t)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns 1 if v is equivalent to u, and 0 otherwise.
|
|
||||||
func (v *Point) Equal(u *Point) int {
|
|
||||||
checkInitialized(v, u)
|
|
||||||
|
|
||||||
var t1, t2, t3, t4 field.Element
|
|
||||||
t1.Multiply(&v.x, &u.z)
|
|
||||||
t2.Multiply(&u.x, &v.z)
|
|
||||||
t3.Multiply(&v.y, &u.z)
|
|
||||||
t4.Multiply(&u.y, &v.z)
|
|
||||||
|
|
||||||
return t1.Equal(&t2) & t3.Equal(&t4)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constant-time operations
|
|
||||||
|
|
||||||
// Select sets v to a if cond == 1 and to b if cond == 0.
|
|
||||||
func (v *projCached) Select(a, b *projCached, cond int) *projCached {
|
|
||||||
v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
|
|
||||||
v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
|
|
||||||
v.Z.Select(&a.Z, &b.Z, cond)
|
|
||||||
v.T2d.Select(&a.T2d, &b.T2d, cond)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select sets v to a if cond == 1 and to b if cond == 0.
|
|
||||||
func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached {
|
|
||||||
v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
|
|
||||||
v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
|
|
||||||
v.T2d.Select(&a.T2d, &b.T2d, cond)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
|
|
||||||
func (v *projCached) CondNeg(cond int) *projCached {
|
|
||||||
v.YplusX.Swap(&v.YminusX, cond)
|
|
||||||
v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
|
|
||||||
func (v *affineCached) CondNeg(cond int) *affineCached {
|
|
||||||
v.YplusX.Swap(&v.YminusX, cond)
|
|
||||||
v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
|
|
||||||
return v
|
|
||||||
}
|
|
343
vendor/filippo.io/edwards25519/extra.go
generated
vendored
343
vendor/filippo.io/edwards25519/extra.go
generated
vendored
@ -1,343 +0,0 @@
|
|||||||
// Copyright (c) 2021 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 edwards25519
|
|
||||||
|
|
||||||
// This file contains additional functionality that is not included in the
|
|
||||||
// upstream crypto/ed25519/internal/edwards25519 package.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"filippo.io/edwards25519/field"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ExtendedCoordinates returns v in extended coordinates (X:Y:Z:T) where
|
|
||||||
// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
|
|
||||||
func (v *Point) ExtendedCoordinates() (X, Y, Z, T *field.Element) {
|
|
||||||
// This function is outlined to make the allocations inline in the caller
|
|
||||||
// rather than happen on the heap. Don't change the style without making
|
|
||||||
// sure it doesn't increase the inliner cost.
|
|
||||||
var e [4]field.Element
|
|
||||||
X, Y, Z, T = v.extendedCoordinates(&e)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Point) extendedCoordinates(e *[4]field.Element) (X, Y, Z, T *field.Element) {
|
|
||||||
checkInitialized(v)
|
|
||||||
X = e[0].Set(&v.x)
|
|
||||||
Y = e[1].Set(&v.y)
|
|
||||||
Z = e[2].Set(&v.z)
|
|
||||||
T = e[3].Set(&v.t)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetExtendedCoordinates sets v = (X:Y:Z:T) in extended coordinates where
|
|
||||||
// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
|
|
||||||
//
|
|
||||||
// If the coordinates are invalid or don't represent a valid point on the curve,
|
|
||||||
// SetExtendedCoordinates returns nil and an error and the receiver is
|
|
||||||
// unchanged. Otherwise, SetExtendedCoordinates returns v.
|
|
||||||
func (v *Point) SetExtendedCoordinates(X, Y, Z, T *field.Element) (*Point, error) {
|
|
||||||
if !isOnCurve(X, Y, Z, T) {
|
|
||||||
return nil, errors.New("edwards25519: invalid point coordinates")
|
|
||||||
}
|
|
||||||
v.x.Set(X)
|
|
||||||
v.y.Set(Y)
|
|
||||||
v.z.Set(Z)
|
|
||||||
v.t.Set(T)
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isOnCurve(X, Y, Z, T *field.Element) bool {
|
|
||||||
var lhs, rhs field.Element
|
|
||||||
XX := new(field.Element).Square(X)
|
|
||||||
YY := new(field.Element).Square(Y)
|
|
||||||
ZZ := new(field.Element).Square(Z)
|
|
||||||
TT := new(field.Element).Square(T)
|
|
||||||
// -x² + y² = 1 + dx²y²
|
|
||||||
// -(X/Z)² + (Y/Z)² = 1 + d(T/Z)²
|
|
||||||
// -X² + Y² = Z² + dT²
|
|
||||||
lhs.Subtract(YY, XX)
|
|
||||||
rhs.Multiply(d, TT).Add(&rhs, ZZ)
|
|
||||||
if lhs.Equal(&rhs) != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// xy = T/Z
|
|
||||||
// XY/Z² = T/Z
|
|
||||||
// XY = TZ
|
|
||||||
lhs.Multiply(X, Y)
|
|
||||||
rhs.Multiply(T, Z)
|
|
||||||
return lhs.Equal(&rhs) == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// BytesMontgomery converts v to a point on the birationally-equivalent
|
|
||||||
// Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding
|
|
||||||
// according to RFC 7748.
|
|
||||||
//
|
|
||||||
// Note that BytesMontgomery only encodes the u-coordinate, so v and -v encode
|
|
||||||
// to the same value. If v is the identity point, BytesMontgomery returns 32
|
|
||||||
// zero bytes, analogously to the X25519 function.
|
|
||||||
func (v *Point) BytesMontgomery() []byte {
|
|
||||||
// This function is outlined to make the allocations inline in the caller
|
|
||||||
// rather than happen on the heap.
|
|
||||||
var buf [32]byte
|
|
||||||
return v.bytesMontgomery(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Point) bytesMontgomery(buf *[32]byte) []byte {
|
|
||||||
checkInitialized(v)
|
|
||||||
|
|
||||||
// RFC 7748, Section 4.1 provides the bilinear map to calculate the
|
|
||||||
// Montgomery u-coordinate
|
|
||||||
//
|
|
||||||
// u = (1 + y) / (1 - y)
|
|
||||||
//
|
|
||||||
// where y = Y / Z.
|
|
||||||
|
|
||||||
var y, recip, u field.Element
|
|
||||||
|
|
||||||
y.Multiply(&v.y, y.Invert(&v.z)) // y = Y / Z
|
|
||||||
recip.Invert(recip.Subtract(feOne, &y)) // r = 1/(1 - y)
|
|
||||||
u.Multiply(u.Add(feOne, &y), &recip) // u = (1 + y)*r
|
|
||||||
|
|
||||||
return copyFieldElement(buf, &u)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MultByCofactor sets v = 8 * p, and returns v.
|
|
||||||
func (v *Point) MultByCofactor(p *Point) *Point {
|
|
||||||
checkInitialized(p)
|
|
||||||
result := projP1xP1{}
|
|
||||||
pp := (&projP2{}).FromP3(p)
|
|
||||||
result.Double(pp)
|
|
||||||
pp.FromP1xP1(&result)
|
|
||||||
result.Double(pp)
|
|
||||||
pp.FromP1xP1(&result)
|
|
||||||
result.Double(pp)
|
|
||||||
return v.fromP1xP1(&result)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given k > 0, set s = s**(2*i).
|
|
||||||
func (s *Scalar) pow2k(k int) {
|
|
||||||
for i := 0; i < k; i++ {
|
|
||||||
s.Multiply(s, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invert sets s to the inverse of a nonzero scalar v, and returns s.
|
|
||||||
//
|
|
||||||
// If t is zero, Invert returns zero.
|
|
||||||
func (s *Scalar) Invert(t *Scalar) *Scalar {
|
|
||||||
// Uses a hardcoded sliding window of width 4.
|
|
||||||
var table [8]Scalar
|
|
||||||
var tt Scalar
|
|
||||||
tt.Multiply(t, t)
|
|
||||||
table[0] = *t
|
|
||||||
for i := 0; i < 7; i++ {
|
|
||||||
table[i+1].Multiply(&table[i], &tt)
|
|
||||||
}
|
|
||||||
// Now table = [t**1, t**3, t**7, t**11, t**13, t**15]
|
|
||||||
// so t**k = t[k/2] for odd k
|
|
||||||
|
|
||||||
// To compute the sliding window digits, use the following Sage script:
|
|
||||||
|
|
||||||
// sage: import itertools
|
|
||||||
// sage: def sliding_window(w,k):
|
|
||||||
// ....: digits = []
|
|
||||||
// ....: while k > 0:
|
|
||||||
// ....: if k % 2 == 1:
|
|
||||||
// ....: kmod = k % (2**w)
|
|
||||||
// ....: digits.append(kmod)
|
|
||||||
// ....: k = k - kmod
|
|
||||||
// ....: else:
|
|
||||||
// ....: digits.append(0)
|
|
||||||
// ....: k = k // 2
|
|
||||||
// ....: return digits
|
|
||||||
|
|
||||||
// Now we can compute s roughly as follows:
|
|
||||||
|
|
||||||
// sage: s = 1
|
|
||||||
// sage: for coeff in reversed(sliding_window(4,l-2)):
|
|
||||||
// ....: s = s*s
|
|
||||||
// ....: if coeff > 0 :
|
|
||||||
// ....: s = s*t**coeff
|
|
||||||
|
|
||||||
// This works on one bit at a time, with many runs of zeros.
|
|
||||||
// The digits can be collapsed into [(count, coeff)] as follows:
|
|
||||||
|
|
||||||
// sage: [(len(list(group)),d) for d,group in itertools.groupby(sliding_window(4,l-2))]
|
|
||||||
|
|
||||||
// Entries of the form (k, 0) turn into pow2k(k)
|
|
||||||
// Entries of the form (1, coeff) turn into a squaring and then a table lookup.
|
|
||||||
// We can fold the squaring into the previous pow2k(k) as pow2k(k+1).
|
|
||||||
|
|
||||||
*s = table[1/2]
|
|
||||||
s.pow2k(127 + 1)
|
|
||||||
s.Multiply(s, &table[1/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[9/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[11/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[13/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[15/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[7/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[15/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[5/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[1/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[15/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[15/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[7/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[3/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[11/2])
|
|
||||||
s.pow2k(5 + 1)
|
|
||||||
s.Multiply(s, &table[11/2])
|
|
||||||
s.pow2k(9 + 1)
|
|
||||||
s.Multiply(s, &table[9/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[3/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[3/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[3/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[9/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[7/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[3/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[13/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[7/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[9/2])
|
|
||||||
s.pow2k(3 + 1)
|
|
||||||
s.Multiply(s, &table[15/2])
|
|
||||||
s.pow2k(4 + 1)
|
|
||||||
s.Multiply(s, &table[11/2])
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// MultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v.
|
|
||||||
//
|
|
||||||
// Execution time depends only on the lengths of the two slices, which must match.
|
|
||||||
func (v *Point) MultiScalarMult(scalars []*Scalar, points []*Point) *Point {
|
|
||||||
if len(scalars) != len(points) {
|
|
||||||
panic("edwards25519: called MultiScalarMult with different size inputs")
|
|
||||||
}
|
|
||||||
checkInitialized(points...)
|
|
||||||
|
|
||||||
// Proceed as in the single-base case, but share doublings
|
|
||||||
// between each point in the multiscalar equation.
|
|
||||||
|
|
||||||
// Build lookup tables for each point
|
|
||||||
tables := make([]projLookupTable, len(points))
|
|
||||||
for i := range tables {
|
|
||||||
tables[i].FromP3(points[i])
|
|
||||||
}
|
|
||||||
// Compute signed radix-16 digits for each scalar
|
|
||||||
digits := make([][64]int8, len(scalars))
|
|
||||||
for i := range digits {
|
|
||||||
digits[i] = scalars[i].signedRadix16()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap first loop iteration to save computing 16*identity
|
|
||||||
multiple := &projCached{}
|
|
||||||
tmp1 := &projP1xP1{}
|
|
||||||
tmp2 := &projP2{}
|
|
||||||
// Lookup-and-add the appropriate multiple of each input point
|
|
||||||
for j := range tables {
|
|
||||||
tables[j].SelectInto(multiple, digits[j][63])
|
|
||||||
tmp1.Add(v, multiple) // tmp1 = v + x_(j,63)*Q in P1xP1 coords
|
|
||||||
v.fromP1xP1(tmp1) // update v
|
|
||||||
}
|
|
||||||
tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration
|
|
||||||
for i := 62; i >= 0; i-- {
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 2*(prev) in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*(prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 4*(prev) in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*(prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 8*(prev) in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*(prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 16*(prev) in P1xP1 coords
|
|
||||||
v.fromP1xP1(tmp1) // v = 16*(prev) in P3 coords
|
|
||||||
// Lookup-and-add the appropriate multiple of each input point
|
|
||||||
for j := range tables {
|
|
||||||
tables[j].SelectInto(multiple, digits[j][i])
|
|
||||||
tmp1.Add(v, multiple) // tmp1 = v + x_(j,i)*Q in P1xP1 coords
|
|
||||||
v.fromP1xP1(tmp1) // update v
|
|
||||||
}
|
|
||||||
tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// VarTimeMultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v.
|
|
||||||
//
|
|
||||||
// Execution time depends on the inputs.
|
|
||||||
func (v *Point) VarTimeMultiScalarMult(scalars []*Scalar, points []*Point) *Point {
|
|
||||||
if len(scalars) != len(points) {
|
|
||||||
panic("edwards25519: called VarTimeMultiScalarMult with different size inputs")
|
|
||||||
}
|
|
||||||
checkInitialized(points...)
|
|
||||||
|
|
||||||
// Generalize double-base NAF computation to arbitrary sizes.
|
|
||||||
// Here all the points are dynamic, so we only use the smaller
|
|
||||||
// tables.
|
|
||||||
|
|
||||||
// Build lookup tables for each point
|
|
||||||
tables := make([]nafLookupTable5, len(points))
|
|
||||||
for i := range tables {
|
|
||||||
tables[i].FromP3(points[i])
|
|
||||||
}
|
|
||||||
// Compute a NAF for each scalar
|
|
||||||
nafs := make([][256]int8, len(scalars))
|
|
||||||
for i := range nafs {
|
|
||||||
nafs[i] = scalars[i].nonAdjacentForm(5)
|
|
||||||
}
|
|
||||||
|
|
||||||
multiple := &projCached{}
|
|
||||||
tmp1 := &projP1xP1{}
|
|
||||||
tmp2 := &projP2{}
|
|
||||||
tmp2.Zero()
|
|
||||||
|
|
||||||
// Move from high to low bits, doubling the accumulator
|
|
||||||
// at each iteration and checking whether there is a nonzero
|
|
||||||
// coefficient to look up a multiple of.
|
|
||||||
//
|
|
||||||
// Skip trying to find the first nonzero coefficent, because
|
|
||||||
// searching might be more work than a few extra doublings.
|
|
||||||
for i := 255; i >= 0; i-- {
|
|
||||||
tmp1.Double(tmp2)
|
|
||||||
|
|
||||||
for j := range nafs {
|
|
||||||
if nafs[j][i] > 0 {
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
tables[j].SelectInto(multiple, nafs[j][i])
|
|
||||||
tmp1.Add(v, multiple)
|
|
||||||
} else if nafs[j][i] < 0 {
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
tables[j].SelectInto(multiple, -nafs[j][i])
|
|
||||||
tmp1.Sub(v, multiple)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp2.FromP1xP1(tmp1)
|
|
||||||
}
|
|
||||||
|
|
||||||
v.fromP2(tmp2)
|
|
||||||
return v
|
|
||||||
}
|
|
420
vendor/filippo.io/edwards25519/field/fe.go
generated
vendored
420
vendor/filippo.io/edwards25519/field/fe.go
generated
vendored
@ -1,420 +0,0 @@
|
|||||||
// Copyright (c) 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 field implements fast arithmetic modulo 2^255-19.
|
|
||||||
package field
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/subtle"
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"math/bits"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Element represents an element of the field GF(2^255-19). Note that this
|
|
||||||
// is not a cryptographically secure group, and should only be used to interact
|
|
||||||
// with edwards25519.Point coordinates.
|
|
||||||
//
|
|
||||||
// This type works similarly to math/big.Int, and all arguments and receivers
|
|
||||||
// are allowed to alias.
|
|
||||||
//
|
|
||||||
// The zero value is a valid zero element.
|
|
||||||
type Element struct {
|
|
||||||
// An element t represents the integer
|
|
||||||
// t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
|
|
||||||
//
|
|
||||||
// Between operations, all limbs are expected to be lower than 2^52.
|
|
||||||
l0 uint64
|
|
||||||
l1 uint64
|
|
||||||
l2 uint64
|
|
||||||
l3 uint64
|
|
||||||
l4 uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
const maskLow51Bits uint64 = (1 << 51) - 1
|
|
||||||
|
|
||||||
var feZero = &Element{0, 0, 0, 0, 0}
|
|
||||||
|
|
||||||
// Zero sets v = 0, and returns v.
|
|
||||||
func (v *Element) Zero() *Element {
|
|
||||||
*v = *feZero
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
var feOne = &Element{1, 0, 0, 0, 0}
|
|
||||||
|
|
||||||
// One sets v = 1, and returns v.
|
|
||||||
func (v *Element) One() *Element {
|
|
||||||
*v = *feOne
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// reduce reduces v modulo 2^255 - 19 and returns it.
|
|
||||||
func (v *Element) reduce() *Element {
|
|
||||||
v.carryPropagate()
|
|
||||||
|
|
||||||
// After the light reduction we now have a field element representation
|
|
||||||
// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
|
|
||||||
|
|
||||||
// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
|
|
||||||
// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
|
|
||||||
c := (v.l0 + 19) >> 51
|
|
||||||
c = (v.l1 + c) >> 51
|
|
||||||
c = (v.l2 + c) >> 51
|
|
||||||
c = (v.l3 + c) >> 51
|
|
||||||
c = (v.l4 + c) >> 51
|
|
||||||
|
|
||||||
// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
|
|
||||||
// effectively applying the reduction identity to the carry.
|
|
||||||
v.l0 += 19 * c
|
|
||||||
|
|
||||||
v.l1 += v.l0 >> 51
|
|
||||||
v.l0 = v.l0 & maskLow51Bits
|
|
||||||
v.l2 += v.l1 >> 51
|
|
||||||
v.l1 = v.l1 & maskLow51Bits
|
|
||||||
v.l3 += v.l2 >> 51
|
|
||||||
v.l2 = v.l2 & maskLow51Bits
|
|
||||||
v.l4 += v.l3 >> 51
|
|
||||||
v.l3 = v.l3 & maskLow51Bits
|
|
||||||
// no additional carry
|
|
||||||
v.l4 = v.l4 & maskLow51Bits
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add sets v = a + b, and returns v.
|
|
||||||
func (v *Element) Add(a, b *Element) *Element {
|
|
||||||
v.l0 = a.l0 + b.l0
|
|
||||||
v.l1 = a.l1 + b.l1
|
|
||||||
v.l2 = a.l2 + b.l2
|
|
||||||
v.l3 = a.l3 + b.l3
|
|
||||||
v.l4 = a.l4 + b.l4
|
|
||||||
// Using the generic implementation here is actually faster than the
|
|
||||||
// assembly. Probably because the body of this function is so simple that
|
|
||||||
// the compiler can figure out better optimizations by inlining the carry
|
|
||||||
// propagation.
|
|
||||||
return v.carryPropagateGeneric()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtract sets v = a - b, and returns v.
|
|
||||||
func (v *Element) Subtract(a, b *Element) *Element {
|
|
||||||
// We first add 2 * p, to guarantee the subtraction won't underflow, and
|
|
||||||
// then subtract b (which can be up to 2^255 + 2^13 * 19).
|
|
||||||
v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
|
|
||||||
v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
|
|
||||||
v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
|
|
||||||
v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
|
|
||||||
v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
|
|
||||||
return v.carryPropagate()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Negate sets v = -a, and returns v.
|
|
||||||
func (v *Element) Negate(a *Element) *Element {
|
|
||||||
return v.Subtract(feZero, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invert sets v = 1/z mod p, and returns v.
|
|
||||||
//
|
|
||||||
// If z == 0, Invert returns v = 0.
|
|
||||||
func (v *Element) Invert(z *Element) *Element {
|
|
||||||
// Inversion is implemented as exponentiation with exponent p − 2. It uses the
|
|
||||||
// same sequence of 255 squarings and 11 multiplications as [Curve25519].
|
|
||||||
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
|
|
||||||
|
|
||||||
z2.Square(z) // 2
|
|
||||||
t.Square(&z2) // 4
|
|
||||||
t.Square(&t) // 8
|
|
||||||
z9.Multiply(&t, z) // 9
|
|
||||||
z11.Multiply(&z9, &z2) // 11
|
|
||||||
t.Square(&z11) // 22
|
|
||||||
z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
|
|
||||||
|
|
||||||
t.Square(&z2_5_0) // 2^6 - 2^1
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
t.Square(&t) // 2^10 - 2^5
|
|
||||||
}
|
|
||||||
z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
|
|
||||||
|
|
||||||
t.Square(&z2_10_0) // 2^11 - 2^1
|
|
||||||
for i := 0; i < 9; i++ {
|
|
||||||
t.Square(&t) // 2^20 - 2^10
|
|
||||||
}
|
|
||||||
z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
|
|
||||||
|
|
||||||
t.Square(&z2_20_0) // 2^21 - 2^1
|
|
||||||
for i := 0; i < 19; i++ {
|
|
||||||
t.Square(&t) // 2^40 - 2^20
|
|
||||||
}
|
|
||||||
t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
|
|
||||||
|
|
||||||
t.Square(&t) // 2^41 - 2^1
|
|
||||||
for i := 0; i < 9; i++ {
|
|
||||||
t.Square(&t) // 2^50 - 2^10
|
|
||||||
}
|
|
||||||
z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
|
|
||||||
|
|
||||||
t.Square(&z2_50_0) // 2^51 - 2^1
|
|
||||||
for i := 0; i < 49; i++ {
|
|
||||||
t.Square(&t) // 2^100 - 2^50
|
|
||||||
}
|
|
||||||
z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
|
|
||||||
|
|
||||||
t.Square(&z2_100_0) // 2^101 - 2^1
|
|
||||||
for i := 0; i < 99; i++ {
|
|
||||||
t.Square(&t) // 2^200 - 2^100
|
|
||||||
}
|
|
||||||
t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
|
|
||||||
|
|
||||||
t.Square(&t) // 2^201 - 2^1
|
|
||||||
for i := 0; i < 49; i++ {
|
|
||||||
t.Square(&t) // 2^250 - 2^50
|
|
||||||
}
|
|
||||||
t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
|
|
||||||
|
|
||||||
t.Square(&t) // 2^251 - 2^1
|
|
||||||
t.Square(&t) // 2^252 - 2^2
|
|
||||||
t.Square(&t) // 2^253 - 2^3
|
|
||||||
t.Square(&t) // 2^254 - 2^4
|
|
||||||
t.Square(&t) // 2^255 - 2^5
|
|
||||||
|
|
||||||
return v.Multiply(&t, &z11) // 2^255 - 21
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set sets v = a, and returns v.
|
|
||||||
func (v *Element) Set(a *Element) *Element {
|
|
||||||
*v = *a
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBytes sets v to x, where x is a 32-byte little-endian encoding. If x is
|
|
||||||
// not of the right length, SetBytes returns nil and an error, and the
|
|
||||||
// receiver is unchanged.
|
|
||||||
//
|
|
||||||
// Consistent with RFC 7748, the most significant bit (the high bit of the
|
|
||||||
// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
|
|
||||||
// are accepted. Note that this is laxer than specified by RFC 8032, but
|
|
||||||
// consistent with most Ed25519 implementations.
|
|
||||||
func (v *Element) SetBytes(x []byte) (*Element, error) {
|
|
||||||
if len(x) != 32 {
|
|
||||||
return nil, errors.New("edwards25519: invalid field element input size")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
|
|
||||||
v.l0 = binary.LittleEndian.Uint64(x[0:8])
|
|
||||||
v.l0 &= maskLow51Bits
|
|
||||||
// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
|
|
||||||
v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
|
|
||||||
v.l1 &= maskLow51Bits
|
|
||||||
// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
|
|
||||||
v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
|
|
||||||
v.l2 &= maskLow51Bits
|
|
||||||
// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
|
|
||||||
v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
|
|
||||||
v.l3 &= maskLow51Bits
|
|
||||||
// Bits 204:255 (bytes 24:32, bits 192:256, shift 12, mask 51).
|
|
||||||
// Note: not bytes 25:33, shift 4, to avoid overread.
|
|
||||||
v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
|
|
||||||
v.l4 &= maskLow51Bits
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the canonical 32-byte little-endian encoding of v.
|
|
||||||
func (v *Element) Bytes() []byte {
|
|
||||||
// This function is outlined to make the allocations inline in the caller
|
|
||||||
// rather than happen on the heap.
|
|
||||||
var out [32]byte
|
|
||||||
return v.bytes(&out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *Element) bytes(out *[32]byte) []byte {
|
|
||||||
t := *v
|
|
||||||
t.reduce()
|
|
||||||
|
|
||||||
var buf [8]byte
|
|
||||||
for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
|
|
||||||
bitsOffset := i * 51
|
|
||||||
binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
|
|
||||||
for i, bb := range buf {
|
|
||||||
off := bitsOffset/8 + i
|
|
||||||
if off >= len(out) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
out[off] |= bb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return out[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns 1 if v and u are equal, and 0 otherwise.
|
|
||||||
func (v *Element) Equal(u *Element) int {
|
|
||||||
sa, sv := u.Bytes(), v.Bytes()
|
|
||||||
return subtle.ConstantTimeCompare(sa, sv)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
|
|
||||||
func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
|
|
||||||
|
|
||||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
|
||||||
func (v *Element) Select(a, b *Element, cond int) *Element {
|
|
||||||
m := mask64Bits(cond)
|
|
||||||
v.l0 = (m & a.l0) | (^m & b.l0)
|
|
||||||
v.l1 = (m & a.l1) | (^m & b.l1)
|
|
||||||
v.l2 = (m & a.l2) | (^m & b.l2)
|
|
||||||
v.l3 = (m & a.l3) | (^m & b.l3)
|
|
||||||
v.l4 = (m & a.l4) | (^m & b.l4)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
|
|
||||||
func (v *Element) Swap(u *Element, cond int) {
|
|
||||||
m := mask64Bits(cond)
|
|
||||||
t := m & (v.l0 ^ u.l0)
|
|
||||||
v.l0 ^= t
|
|
||||||
u.l0 ^= t
|
|
||||||
t = m & (v.l1 ^ u.l1)
|
|
||||||
v.l1 ^= t
|
|
||||||
u.l1 ^= t
|
|
||||||
t = m & (v.l2 ^ u.l2)
|
|
||||||
v.l2 ^= t
|
|
||||||
u.l2 ^= t
|
|
||||||
t = m & (v.l3 ^ u.l3)
|
|
||||||
v.l3 ^= t
|
|
||||||
u.l3 ^= t
|
|
||||||
t = m & (v.l4 ^ u.l4)
|
|
||||||
v.l4 ^= t
|
|
||||||
u.l4 ^= t
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNegative returns 1 if v is negative, and 0 otherwise.
|
|
||||||
func (v *Element) IsNegative() int {
|
|
||||||
return int(v.Bytes()[0] & 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Absolute sets v to |u|, and returns v.
|
|
||||||
func (v *Element) Absolute(u *Element) *Element {
|
|
||||||
return v.Select(new(Element).Negate(u), u, u.IsNegative())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiply sets v = x * y, and returns v.
|
|
||||||
func (v *Element) Multiply(x, y *Element) *Element {
|
|
||||||
feMul(v, x, y)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Square sets v = x * x, and returns v.
|
|
||||||
func (v *Element) Square(x *Element) *Element {
|
|
||||||
feSquare(v, x)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mult32 sets v = x * y, and returns v.
|
|
||||||
func (v *Element) Mult32(x *Element, y uint32) *Element {
|
|
||||||
x0lo, x0hi := mul51(x.l0, y)
|
|
||||||
x1lo, x1hi := mul51(x.l1, y)
|
|
||||||
x2lo, x2hi := mul51(x.l2, y)
|
|
||||||
x3lo, x3hi := mul51(x.l3, y)
|
|
||||||
x4lo, x4hi := mul51(x.l4, y)
|
|
||||||
v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
|
|
||||||
v.l1 = x1lo + x0hi
|
|
||||||
v.l2 = x2lo + x1hi
|
|
||||||
v.l3 = x3lo + x2hi
|
|
||||||
v.l4 = x4lo + x3hi
|
|
||||||
// The hi portions are going to be only 32 bits, plus any previous excess,
|
|
||||||
// so we can skip the carry propagation.
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// mul51 returns lo + hi * 2⁵¹ = a * b.
|
|
||||||
func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
|
|
||||||
mh, ml := bits.Mul64(a, uint64(b))
|
|
||||||
lo = ml & maskLow51Bits
|
|
||||||
hi = (mh << 13) | (ml >> 51)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
|
|
||||||
func (v *Element) Pow22523(x *Element) *Element {
|
|
||||||
var t0, t1, t2 Element
|
|
||||||
|
|
||||||
t0.Square(x) // x^2
|
|
||||||
t1.Square(&t0) // x^4
|
|
||||||
t1.Square(&t1) // x^8
|
|
||||||
t1.Multiply(x, &t1) // x^9
|
|
||||||
t0.Multiply(&t0, &t1) // x^11
|
|
||||||
t0.Square(&t0) // x^22
|
|
||||||
t0.Multiply(&t1, &t0) // x^31
|
|
||||||
t1.Square(&t0) // x^62
|
|
||||||
for i := 1; i < 5; i++ { // x^992
|
|
||||||
t1.Square(&t1)
|
|
||||||
}
|
|
||||||
t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1
|
|
||||||
t1.Square(&t0) // 2^11 - 2
|
|
||||||
for i := 1; i < 10; i++ { // 2^20 - 2^10
|
|
||||||
t1.Square(&t1)
|
|
||||||
}
|
|
||||||
t1.Multiply(&t1, &t0) // 2^20 - 1
|
|
||||||
t2.Square(&t1) // 2^21 - 2
|
|
||||||
for i := 1; i < 20; i++ { // 2^40 - 2^20
|
|
||||||
t2.Square(&t2)
|
|
||||||
}
|
|
||||||
t1.Multiply(&t2, &t1) // 2^40 - 1
|
|
||||||
t1.Square(&t1) // 2^41 - 2
|
|
||||||
for i := 1; i < 10; i++ { // 2^50 - 2^10
|
|
||||||
t1.Square(&t1)
|
|
||||||
}
|
|
||||||
t0.Multiply(&t1, &t0) // 2^50 - 1
|
|
||||||
t1.Square(&t0) // 2^51 - 2
|
|
||||||
for i := 1; i < 50; i++ { // 2^100 - 2^50
|
|
||||||
t1.Square(&t1)
|
|
||||||
}
|
|
||||||
t1.Multiply(&t1, &t0) // 2^100 - 1
|
|
||||||
t2.Square(&t1) // 2^101 - 2
|
|
||||||
for i := 1; i < 100; i++ { // 2^200 - 2^100
|
|
||||||
t2.Square(&t2)
|
|
||||||
}
|
|
||||||
t1.Multiply(&t2, &t1) // 2^200 - 1
|
|
||||||
t1.Square(&t1) // 2^201 - 2
|
|
||||||
for i := 1; i < 50; i++ { // 2^250 - 2^50
|
|
||||||
t1.Square(&t1)
|
|
||||||
}
|
|
||||||
t0.Multiply(&t1, &t0) // 2^250 - 1
|
|
||||||
t0.Square(&t0) // 2^251 - 2
|
|
||||||
t0.Square(&t0) // 2^252 - 4
|
|
||||||
return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
|
|
||||||
}
|
|
||||||
|
|
||||||
// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
|
|
||||||
var sqrtM1 = &Element{1718705420411056, 234908883556509,
|
|
||||||
2233514472574048, 2117202627021982, 765476049583133}
|
|
||||||
|
|
||||||
// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
|
|
||||||
//
|
|
||||||
// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
|
|
||||||
// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
|
|
||||||
// and returns r and 0.
|
|
||||||
func (r *Element) SqrtRatio(u, v *Element) (R *Element, wasSquare int) {
|
|
||||||
t0 := new(Element)
|
|
||||||
|
|
||||||
// r = (u * v3) * (u * v7)^((p-5)/8)
|
|
||||||
v2 := new(Element).Square(v)
|
|
||||||
uv3 := new(Element).Multiply(u, t0.Multiply(v2, v))
|
|
||||||
uv7 := new(Element).Multiply(uv3, t0.Square(v2))
|
|
||||||
rr := new(Element).Multiply(uv3, t0.Pow22523(uv7))
|
|
||||||
|
|
||||||
check := new(Element).Multiply(v, t0.Square(rr)) // check = v * r^2
|
|
||||||
|
|
||||||
uNeg := new(Element).Negate(u)
|
|
||||||
correctSignSqrt := check.Equal(u)
|
|
||||||
flippedSignSqrt := check.Equal(uNeg)
|
|
||||||
flippedSignSqrtI := check.Equal(t0.Multiply(uNeg, sqrtM1))
|
|
||||||
|
|
||||||
rPrime := new(Element).Multiply(rr, sqrtM1) // r_prime = SQRT_M1 * r
|
|
||||||
// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
|
|
||||||
rr.Select(rPrime, rr, flippedSignSqrt|flippedSignSqrtI)
|
|
||||||
|
|
||||||
r.Absolute(rr) // Choose the nonnegative square root.
|
|
||||||
return r, correctSignSqrt | flippedSignSqrt
|
|
||||||
}
|
|
13
vendor/filippo.io/edwards25519/field/fe_amd64.go
generated
vendored
13
vendor/filippo.io/edwards25519/field/fe_amd64.go
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build amd64,gc,!purego
|
|
||||||
|
|
||||||
package field
|
|
||||||
|
|
||||||
// feMul sets out = a * b. It works like feMulGeneric.
|
|
||||||
//go:noescape
|
|
||||||
func feMul(out *Element, a *Element, b *Element)
|
|
||||||
|
|
||||||
// feSquare sets out = a * a. It works like feSquareGeneric.
|
|
||||||
//go:noescape
|
|
||||||
func feSquare(out *Element, a *Element)
|
|
378
vendor/filippo.io/edwards25519/field/fe_amd64.s
generated
vendored
378
vendor/filippo.io/edwards25519/field/fe_amd64.s
generated
vendored
@ -1,378 +0,0 @@
|
|||||||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build amd64,gc,!purego
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// func feMul(out *Element, a *Element, b *Element)
|
|
||||||
TEXT ·feMul(SB), NOSPLIT, $0-24
|
|
||||||
MOVQ a+8(FP), CX
|
|
||||||
MOVQ b+16(FP), BX
|
|
||||||
|
|
||||||
// r0 = a0×b0
|
|
||||||
MOVQ (CX), AX
|
|
||||||
MULQ (BX)
|
|
||||||
MOVQ AX, DI
|
|
||||||
MOVQ DX, SI
|
|
||||||
|
|
||||||
// r0 += 19×a1×b4
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 32(BX)
|
|
||||||
ADDQ AX, DI
|
|
||||||
ADCQ DX, SI
|
|
||||||
|
|
||||||
// r0 += 19×a2×b3
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 24(BX)
|
|
||||||
ADDQ AX, DI
|
|
||||||
ADCQ DX, SI
|
|
||||||
|
|
||||||
// r0 += 19×a3×b2
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 16(BX)
|
|
||||||
ADDQ AX, DI
|
|
||||||
ADCQ DX, SI
|
|
||||||
|
|
||||||
// r0 += 19×a4×b1
|
|
||||||
MOVQ 32(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 8(BX)
|
|
||||||
ADDQ AX, DI
|
|
||||||
ADCQ DX, SI
|
|
||||||
|
|
||||||
// r1 = a0×b1
|
|
||||||
MOVQ (CX), AX
|
|
||||||
MULQ 8(BX)
|
|
||||||
MOVQ AX, R9
|
|
||||||
MOVQ DX, R8
|
|
||||||
|
|
||||||
// r1 += a1×b0
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
MULQ (BX)
|
|
||||||
ADDQ AX, R9
|
|
||||||
ADCQ DX, R8
|
|
||||||
|
|
||||||
// r1 += 19×a2×b4
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 32(BX)
|
|
||||||
ADDQ AX, R9
|
|
||||||
ADCQ DX, R8
|
|
||||||
|
|
||||||
// r1 += 19×a3×b3
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 24(BX)
|
|
||||||
ADDQ AX, R9
|
|
||||||
ADCQ DX, R8
|
|
||||||
|
|
||||||
// r1 += 19×a4×b2
|
|
||||||
MOVQ 32(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 16(BX)
|
|
||||||
ADDQ AX, R9
|
|
||||||
ADCQ DX, R8
|
|
||||||
|
|
||||||
// r2 = a0×b2
|
|
||||||
MOVQ (CX), AX
|
|
||||||
MULQ 16(BX)
|
|
||||||
MOVQ AX, R11
|
|
||||||
MOVQ DX, R10
|
|
||||||
|
|
||||||
// r2 += a1×b1
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
MULQ 8(BX)
|
|
||||||
ADDQ AX, R11
|
|
||||||
ADCQ DX, R10
|
|
||||||
|
|
||||||
// r2 += a2×b0
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
MULQ (BX)
|
|
||||||
ADDQ AX, R11
|
|
||||||
ADCQ DX, R10
|
|
||||||
|
|
||||||
// r2 += 19×a3×b4
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 32(BX)
|
|
||||||
ADDQ AX, R11
|
|
||||||
ADCQ DX, R10
|
|
||||||
|
|
||||||
// r2 += 19×a4×b3
|
|
||||||
MOVQ 32(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 24(BX)
|
|
||||||
ADDQ AX, R11
|
|
||||||
ADCQ DX, R10
|
|
||||||
|
|
||||||
// r3 = a0×b3
|
|
||||||
MOVQ (CX), AX
|
|
||||||
MULQ 24(BX)
|
|
||||||
MOVQ AX, R13
|
|
||||||
MOVQ DX, R12
|
|
||||||
|
|
||||||
// r3 += a1×b2
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
MULQ 16(BX)
|
|
||||||
ADDQ AX, R13
|
|
||||||
ADCQ DX, R12
|
|
||||||
|
|
||||||
// r3 += a2×b1
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
MULQ 8(BX)
|
|
||||||
ADDQ AX, R13
|
|
||||||
ADCQ DX, R12
|
|
||||||
|
|
||||||
// r3 += a3×b0
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
MULQ (BX)
|
|
||||||
ADDQ AX, R13
|
|
||||||
ADCQ DX, R12
|
|
||||||
|
|
||||||
// r3 += 19×a4×b4
|
|
||||||
MOVQ 32(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 32(BX)
|
|
||||||
ADDQ AX, R13
|
|
||||||
ADCQ DX, R12
|
|
||||||
|
|
||||||
// r4 = a0×b4
|
|
||||||
MOVQ (CX), AX
|
|
||||||
MULQ 32(BX)
|
|
||||||
MOVQ AX, R15
|
|
||||||
MOVQ DX, R14
|
|
||||||
|
|
||||||
// r4 += a1×b3
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
MULQ 24(BX)
|
|
||||||
ADDQ AX, R15
|
|
||||||
ADCQ DX, R14
|
|
||||||
|
|
||||||
// r4 += a2×b2
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
MULQ 16(BX)
|
|
||||||
ADDQ AX, R15
|
|
||||||
ADCQ DX, R14
|
|
||||||
|
|
||||||
// r4 += a3×b1
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
MULQ 8(BX)
|
|
||||||
ADDQ AX, R15
|
|
||||||
ADCQ DX, R14
|
|
||||||
|
|
||||||
// r4 += a4×b0
|
|
||||||
MOVQ 32(CX), AX
|
|
||||||
MULQ (BX)
|
|
||||||
ADDQ AX, R15
|
|
||||||
ADCQ DX, R14
|
|
||||||
|
|
||||||
// First reduction chain
|
|
||||||
MOVQ $0x0007ffffffffffff, AX
|
|
||||||
SHLQ $0x0d, DI, SI
|
|
||||||
SHLQ $0x0d, R9, R8
|
|
||||||
SHLQ $0x0d, R11, R10
|
|
||||||
SHLQ $0x0d, R13, R12
|
|
||||||
SHLQ $0x0d, R15, R14
|
|
||||||
ANDQ AX, DI
|
|
||||||
IMUL3Q $0x13, R14, R14
|
|
||||||
ADDQ R14, DI
|
|
||||||
ANDQ AX, R9
|
|
||||||
ADDQ SI, R9
|
|
||||||
ANDQ AX, R11
|
|
||||||
ADDQ R8, R11
|
|
||||||
ANDQ AX, R13
|
|
||||||
ADDQ R10, R13
|
|
||||||
ANDQ AX, R15
|
|
||||||
ADDQ R12, R15
|
|
||||||
|
|
||||||
// Second reduction chain (carryPropagate)
|
|
||||||
MOVQ DI, SI
|
|
||||||
SHRQ $0x33, SI
|
|
||||||
MOVQ R9, R8
|
|
||||||
SHRQ $0x33, R8
|
|
||||||
MOVQ R11, R10
|
|
||||||
SHRQ $0x33, R10
|
|
||||||
MOVQ R13, R12
|
|
||||||
SHRQ $0x33, R12
|
|
||||||
MOVQ R15, R14
|
|
||||||
SHRQ $0x33, R14
|
|
||||||
ANDQ AX, DI
|
|
||||||
IMUL3Q $0x13, R14, R14
|
|
||||||
ADDQ R14, DI
|
|
||||||
ANDQ AX, R9
|
|
||||||
ADDQ SI, R9
|
|
||||||
ANDQ AX, R11
|
|
||||||
ADDQ R8, R11
|
|
||||||
ANDQ AX, R13
|
|
||||||
ADDQ R10, R13
|
|
||||||
ANDQ AX, R15
|
|
||||||
ADDQ R12, R15
|
|
||||||
|
|
||||||
// Store output
|
|
||||||
MOVQ out+0(FP), AX
|
|
||||||
MOVQ DI, (AX)
|
|
||||||
MOVQ R9, 8(AX)
|
|
||||||
MOVQ R11, 16(AX)
|
|
||||||
MOVQ R13, 24(AX)
|
|
||||||
MOVQ R15, 32(AX)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func feSquare(out *Element, a *Element)
|
|
||||||
TEXT ·feSquare(SB), NOSPLIT, $0-16
|
|
||||||
MOVQ a+8(FP), CX
|
|
||||||
|
|
||||||
// r0 = l0×l0
|
|
||||||
MOVQ (CX), AX
|
|
||||||
MULQ (CX)
|
|
||||||
MOVQ AX, SI
|
|
||||||
MOVQ DX, BX
|
|
||||||
|
|
||||||
// r0 += 38×l1×l4
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
IMUL3Q $0x26, AX, AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX, SI
|
|
||||||
ADCQ DX, BX
|
|
||||||
|
|
||||||
// r0 += 38×l2×l3
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
IMUL3Q $0x26, AX, AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX, SI
|
|
||||||
ADCQ DX, BX
|
|
||||||
|
|
||||||
// r1 = 2×l0×l1
|
|
||||||
MOVQ (CX), AX
|
|
||||||
SHLQ $0x01, AX
|
|
||||||
MULQ 8(CX)
|
|
||||||
MOVQ AX, R8
|
|
||||||
MOVQ DX, DI
|
|
||||||
|
|
||||||
// r1 += 38×l2×l4
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
IMUL3Q $0x26, AX, AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX, R8
|
|
||||||
ADCQ DX, DI
|
|
||||||
|
|
||||||
// r1 += 19×l3×l3
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX, R8
|
|
||||||
ADCQ DX, DI
|
|
||||||
|
|
||||||
// r2 = 2×l0×l2
|
|
||||||
MOVQ (CX), AX
|
|
||||||
SHLQ $0x01, AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
MOVQ AX, R10
|
|
||||||
MOVQ DX, R9
|
|
||||||
|
|
||||||
// r2 += l1×l1
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
MULQ 8(CX)
|
|
||||||
ADDQ AX, R10
|
|
||||||
ADCQ DX, R9
|
|
||||||
|
|
||||||
// r2 += 38×l3×l4
|
|
||||||
MOVQ 24(CX), AX
|
|
||||||
IMUL3Q $0x26, AX, AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX, R10
|
|
||||||
ADCQ DX, R9
|
|
||||||
|
|
||||||
// r3 = 2×l0×l3
|
|
||||||
MOVQ (CX), AX
|
|
||||||
SHLQ $0x01, AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
MOVQ AX, R12
|
|
||||||
MOVQ DX, R11
|
|
||||||
|
|
||||||
// r3 += 2×l1×l2
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
IMUL3Q $0x02, AX, AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
ADDQ AX, R12
|
|
||||||
ADCQ DX, R11
|
|
||||||
|
|
||||||
// r3 += 19×l4×l4
|
|
||||||
MOVQ 32(CX), AX
|
|
||||||
IMUL3Q $0x13, AX, AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
ADDQ AX, R12
|
|
||||||
ADCQ DX, R11
|
|
||||||
|
|
||||||
// r4 = 2×l0×l4
|
|
||||||
MOVQ (CX), AX
|
|
||||||
SHLQ $0x01, AX
|
|
||||||
MULQ 32(CX)
|
|
||||||
MOVQ AX, R14
|
|
||||||
MOVQ DX, R13
|
|
||||||
|
|
||||||
// r4 += 2×l1×l3
|
|
||||||
MOVQ 8(CX), AX
|
|
||||||
IMUL3Q $0x02, AX, AX
|
|
||||||
MULQ 24(CX)
|
|
||||||
ADDQ AX, R14
|
|
||||||
ADCQ DX, R13
|
|
||||||
|
|
||||||
// r4 += l2×l2
|
|
||||||
MOVQ 16(CX), AX
|
|
||||||
MULQ 16(CX)
|
|
||||||
ADDQ AX, R14
|
|
||||||
ADCQ DX, R13
|
|
||||||
|
|
||||||
// First reduction chain
|
|
||||||
MOVQ $0x0007ffffffffffff, AX
|
|
||||||
SHLQ $0x0d, SI, BX
|
|
||||||
SHLQ $0x0d, R8, DI
|
|
||||||
SHLQ $0x0d, R10, R9
|
|
||||||
SHLQ $0x0d, R12, R11
|
|
||||||
SHLQ $0x0d, R14, R13
|
|
||||||
ANDQ AX, SI
|
|
||||||
IMUL3Q $0x13, R13, R13
|
|
||||||
ADDQ R13, SI
|
|
||||||
ANDQ AX, R8
|
|
||||||
ADDQ BX, R8
|
|
||||||
ANDQ AX, R10
|
|
||||||
ADDQ DI, R10
|
|
||||||
ANDQ AX, R12
|
|
||||||
ADDQ R9, R12
|
|
||||||
ANDQ AX, R14
|
|
||||||
ADDQ R11, R14
|
|
||||||
|
|
||||||
// Second reduction chain (carryPropagate)
|
|
||||||
MOVQ SI, BX
|
|
||||||
SHRQ $0x33, BX
|
|
||||||
MOVQ R8, DI
|
|
||||||
SHRQ $0x33, DI
|
|
||||||
MOVQ R10, R9
|
|
||||||
SHRQ $0x33, R9
|
|
||||||
MOVQ R12, R11
|
|
||||||
SHRQ $0x33, R11
|
|
||||||
MOVQ R14, R13
|
|
||||||
SHRQ $0x33, R13
|
|
||||||
ANDQ AX, SI
|
|
||||||
IMUL3Q $0x13, R13, R13
|
|
||||||
ADDQ R13, SI
|
|
||||||
ANDQ AX, R8
|
|
||||||
ADDQ BX, R8
|
|
||||||
ANDQ AX, R10
|
|
||||||
ADDQ DI, R10
|
|
||||||
ANDQ AX, R12
|
|
||||||
ADDQ R9, R12
|
|
||||||
ANDQ AX, R14
|
|
||||||
ADDQ R11, R14
|
|
||||||
|
|
||||||
// Store output
|
|
||||||
MOVQ out+0(FP), AX
|
|
||||||
MOVQ SI, (AX)
|
|
||||||
MOVQ R8, 8(AX)
|
|
||||||
MOVQ R10, 16(AX)
|
|
||||||
MOVQ R12, 24(AX)
|
|
||||||
MOVQ R14, 32(AX)
|
|
||||||
RET
|
|
12
vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go
generated
vendored
12
vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// Copyright (c) 2019 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.
|
|
||||||
|
|
||||||
//go:build !amd64 || !gc || purego
|
|
||||||
// +build !amd64 !gc purego
|
|
||||||
|
|
||||||
package field
|
|
||||||
|
|
||||||
func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
|
|
||||||
|
|
||||||
func feSquare(v, x *Element) { feSquareGeneric(v, x) }
|
|
16
vendor/filippo.io/edwards25519/field/fe_arm64.go
generated
vendored
16
vendor/filippo.io/edwards25519/field/fe_arm64.go
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
// Copyright (c) 2020 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.
|
|
||||||
|
|
||||||
//go:build arm64 && gc && !purego
|
|
||||||
// +build arm64,gc,!purego
|
|
||||||
|
|
||||||
package field
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
func carryPropagate(v *Element)
|
|
||||||
|
|
||||||
func (v *Element) carryPropagate() *Element {
|
|
||||||
carryPropagate(v)
|
|
||||||
return v
|
|
||||||
}
|
|
42
vendor/filippo.io/edwards25519/field/fe_arm64.s
generated
vendored
42
vendor/filippo.io/edwards25519/field/fe_arm64.s
generated
vendored
@ -1,42 +0,0 @@
|
|||||||
// Copyright (c) 2020 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.
|
|
||||||
|
|
||||||
// +build arm64,gc,!purego
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// carryPropagate works exactly like carryPropagateGeneric and uses the
|
|
||||||
// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
|
|
||||||
// avoids loading R0-R4 twice and uses LDP and STP.
|
|
||||||
//
|
|
||||||
// See https://golang.org/issues/43145 for the main compiler issue.
|
|
||||||
//
|
|
||||||
// func carryPropagate(v *Element)
|
|
||||||
TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
|
|
||||||
MOVD v+0(FP), R20
|
|
||||||
|
|
||||||
LDP 0(R20), (R0, R1)
|
|
||||||
LDP 16(R20), (R2, R3)
|
|
||||||
MOVD 32(R20), R4
|
|
||||||
|
|
||||||
AND $0x7ffffffffffff, R0, R10
|
|
||||||
AND $0x7ffffffffffff, R1, R11
|
|
||||||
AND $0x7ffffffffffff, R2, R12
|
|
||||||
AND $0x7ffffffffffff, R3, R13
|
|
||||||
AND $0x7ffffffffffff, R4, R14
|
|
||||||
|
|
||||||
ADD R0>>51, R11, R11
|
|
||||||
ADD R1>>51, R12, R12
|
|
||||||
ADD R2>>51, R13, R13
|
|
||||||
ADD R3>>51, R14, R14
|
|
||||||
// R4>>51 * 19 + R10 -> R10
|
|
||||||
LSR $51, R4, R21
|
|
||||||
MOVD $19, R22
|
|
||||||
MADD R22, R10, R21, R10
|
|
||||||
|
|
||||||
STP (R10, R11), 0(R20)
|
|
||||||
STP (R12, R13), 16(R20)
|
|
||||||
MOVD R14, 32(R20)
|
|
||||||
|
|
||||||
RET
|
|
12
vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go
generated
vendored
12
vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// Copyright (c) 2021 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.
|
|
||||||
|
|
||||||
//go:build !arm64 || !gc || purego
|
|
||||||
// +build !arm64 !gc purego
|
|
||||||
|
|
||||||
package field
|
|
||||||
|
|
||||||
func (v *Element) carryPropagate() *Element {
|
|
||||||
return v.carryPropagateGeneric()
|
|
||||||
}
|
|
50
vendor/filippo.io/edwards25519/field/fe_extra.go
generated
vendored
50
vendor/filippo.io/edwards25519/field/fe_extra.go
generated
vendored
@ -1,50 +0,0 @@
|
|||||||
// Copyright (c) 2021 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 field
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// This file contains additional functionality that is not included in the
|
|
||||||
// upstream crypto/ed25519/internal/edwards25519/field package.
|
|
||||||
|
|
||||||
// SetWideBytes sets v to x, where x is a 64-byte little-endian encoding, which
|
|
||||||
// is reduced modulo the field order. If x is not of the right length,
|
|
||||||
// SetWideBytes returns nil and an error, and the receiver is unchanged.
|
|
||||||
//
|
|
||||||
// SetWideBytes is not necessary to select a uniformly distributed value, and is
|
|
||||||
// only provided for compatibility: SetBytes can be used instead as the chance
|
|
||||||
// of bias is less than 2⁻²⁵⁰.
|
|
||||||
func (v *Element) SetWideBytes(x []byte) (*Element, error) {
|
|
||||||
if len(x) != 64 {
|
|
||||||
return nil, errors.New("edwards25519: invalid SetWideBytes input size")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split the 64 bytes into two elements, and extract the most significant
|
|
||||||
// bit of each, which is ignored by SetBytes.
|
|
||||||
lo, _ := new(Element).SetBytes(x[:32])
|
|
||||||
loMSB := uint64(x[31] >> 7)
|
|
||||||
hi, _ := new(Element).SetBytes(x[32:])
|
|
||||||
hiMSB := uint64(x[63] >> 7)
|
|
||||||
|
|
||||||
// The output we want is
|
|
||||||
//
|
|
||||||
// v = lo + loMSB * 2²⁵⁵ + hi * 2²⁵⁶ + hiMSB * 2⁵¹¹
|
|
||||||
//
|
|
||||||
// which applying the reduction identity comes out to
|
|
||||||
//
|
|
||||||
// v = lo + loMSB * 19 + hi * 2 * 19 + hiMSB * 2 * 19²
|
|
||||||
//
|
|
||||||
// l0 will be the sum of a 52 bits value (lo.l0), plus a 5 bits value
|
|
||||||
// (loMSB * 19), a 6 bits value (hi.l0 * 2 * 19), and a 10 bits value
|
|
||||||
// (hiMSB * 2 * 19²), so it fits in a uint64.
|
|
||||||
|
|
||||||
v.l0 = lo.l0 + loMSB*19 + hi.l0*2*19 + hiMSB*2*19*19
|
|
||||||
v.l1 = lo.l1 + hi.l1*2*19
|
|
||||||
v.l2 = lo.l2 + hi.l2*2*19
|
|
||||||
v.l3 = lo.l3 + hi.l3*2*19
|
|
||||||
v.l4 = lo.l4 + hi.l4*2*19
|
|
||||||
|
|
||||||
return v.carryPropagate(), nil
|
|
||||||
}
|
|
266
vendor/filippo.io/edwards25519/field/fe_generic.go
generated
vendored
266
vendor/filippo.io/edwards25519/field/fe_generic.go
generated
vendored
@ -1,266 +0,0 @@
|
|||||||
// Copyright (c) 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 field
|
|
||||||
|
|
||||||
import "math/bits"
|
|
||||||
|
|
||||||
// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
|
|
||||||
// bits.Mul64 and bits.Add64 intrinsics.
|
|
||||||
type uint128 struct {
|
|
||||||
lo, hi uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// mul64 returns a * b.
|
|
||||||
func mul64(a, b uint64) uint128 {
|
|
||||||
hi, lo := bits.Mul64(a, b)
|
|
||||||
return uint128{lo, hi}
|
|
||||||
}
|
|
||||||
|
|
||||||
// addMul64 returns v + a * b.
|
|
||||||
func addMul64(v uint128, a, b uint64) uint128 {
|
|
||||||
hi, lo := bits.Mul64(a, b)
|
|
||||||
lo, c := bits.Add64(lo, v.lo, 0)
|
|
||||||
hi, _ = bits.Add64(hi, v.hi, c)
|
|
||||||
return uint128{lo, hi}
|
|
||||||
}
|
|
||||||
|
|
||||||
// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
|
|
||||||
func shiftRightBy51(a uint128) uint64 {
|
|
||||||
return (a.hi << (64 - 51)) | (a.lo >> 51)
|
|
||||||
}
|
|
||||||
|
|
||||||
func feMulGeneric(v, a, b *Element) {
|
|
||||||
a0 := a.l0
|
|
||||||
a1 := a.l1
|
|
||||||
a2 := a.l2
|
|
||||||
a3 := a.l3
|
|
||||||
a4 := a.l4
|
|
||||||
|
|
||||||
b0 := b.l0
|
|
||||||
b1 := b.l1
|
|
||||||
b2 := b.l2
|
|
||||||
b3 := b.l3
|
|
||||||
b4 := b.l4
|
|
||||||
|
|
||||||
// Limb multiplication works like pen-and-paper columnar multiplication, but
|
|
||||||
// with 51-bit limbs instead of digits.
|
|
||||||
//
|
|
||||||
// a4 a3 a2 a1 a0 x
|
|
||||||
// b4 b3 b2 b1 b0 =
|
|
||||||
// ------------------------
|
|
||||||
// a4b0 a3b0 a2b0 a1b0 a0b0 +
|
|
||||||
// a4b1 a3b1 a2b1 a1b1 a0b1 +
|
|
||||||
// a4b2 a3b2 a2b2 a1b2 a0b2 +
|
|
||||||
// a4b3 a3b3 a2b3 a1b3 a0b3 +
|
|
||||||
// a4b4 a3b4 a2b4 a1b4 a0b4 =
|
|
||||||
// ----------------------------------------------
|
|
||||||
// r8 r7 r6 r5 r4 r3 r2 r1 r0
|
|
||||||
//
|
|
||||||
// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
|
|
||||||
// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
|
|
||||||
// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
|
|
||||||
//
|
|
||||||
// Reduction can be carried out simultaneously to multiplication. For
|
|
||||||
// example, we do not compute r5: whenever the result of a multiplication
|
|
||||||
// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
|
|
||||||
//
|
|
||||||
// a4b0 a3b0 a2b0 a1b0 a0b0 +
|
|
||||||
// a3b1 a2b1 a1b1 a0b1 19×a4b1 +
|
|
||||||
// a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
|
|
||||||
// a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
|
|
||||||
// a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
|
|
||||||
// --------------------------------------
|
|
||||||
// r4 r3 r2 r1 r0
|
|
||||||
//
|
|
||||||
// Finally we add up the columns into wide, overlapping limbs.
|
|
||||||
|
|
||||||
a1_19 := a1 * 19
|
|
||||||
a2_19 := a2 * 19
|
|
||||||
a3_19 := a3 * 19
|
|
||||||
a4_19 := a4 * 19
|
|
||||||
|
|
||||||
// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
|
|
||||||
r0 := mul64(a0, b0)
|
|
||||||
r0 = addMul64(r0, a1_19, b4)
|
|
||||||
r0 = addMul64(r0, a2_19, b3)
|
|
||||||
r0 = addMul64(r0, a3_19, b2)
|
|
||||||
r0 = addMul64(r0, a4_19, b1)
|
|
||||||
|
|
||||||
// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
|
|
||||||
r1 := mul64(a0, b1)
|
|
||||||
r1 = addMul64(r1, a1, b0)
|
|
||||||
r1 = addMul64(r1, a2_19, b4)
|
|
||||||
r1 = addMul64(r1, a3_19, b3)
|
|
||||||
r1 = addMul64(r1, a4_19, b2)
|
|
||||||
|
|
||||||
// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
|
|
||||||
r2 := mul64(a0, b2)
|
|
||||||
r2 = addMul64(r2, a1, b1)
|
|
||||||
r2 = addMul64(r2, a2, b0)
|
|
||||||
r2 = addMul64(r2, a3_19, b4)
|
|
||||||
r2 = addMul64(r2, a4_19, b3)
|
|
||||||
|
|
||||||
// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
|
|
||||||
r3 := mul64(a0, b3)
|
|
||||||
r3 = addMul64(r3, a1, b2)
|
|
||||||
r3 = addMul64(r3, a2, b1)
|
|
||||||
r3 = addMul64(r3, a3, b0)
|
|
||||||
r3 = addMul64(r3, a4_19, b4)
|
|
||||||
|
|
||||||
// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
|
|
||||||
r4 := mul64(a0, b4)
|
|
||||||
r4 = addMul64(r4, a1, b3)
|
|
||||||
r4 = addMul64(r4, a2, b2)
|
|
||||||
r4 = addMul64(r4, a3, b1)
|
|
||||||
r4 = addMul64(r4, a4, b0)
|
|
||||||
|
|
||||||
// After the multiplication, we need to reduce (carry) the five coefficients
|
|
||||||
// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
|
|
||||||
// to respect the Element invariant.
|
|
||||||
//
|
|
||||||
// Overall, the reduction works the same as carryPropagate, except with
|
|
||||||
// wider inputs: we take the carry for each coefficient by shifting it right
|
|
||||||
// by 51, and add it to the limb above it. The top carry is multiplied by 19
|
|
||||||
// according to the reduction identity and added to the lowest limb.
|
|
||||||
//
|
|
||||||
// The largest coefficient (r0) will be at most 111 bits, which guarantees
|
|
||||||
// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
|
|
||||||
//
|
|
||||||
// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
|
|
||||||
// r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
|
|
||||||
// r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
|
|
||||||
// r0 < 2⁷ × 2⁵² × 2⁵²
|
|
||||||
// r0 < 2¹¹¹
|
|
||||||
//
|
|
||||||
// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
|
|
||||||
// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
|
|
||||||
// allows us to easily apply the reduction identity.
|
|
||||||
//
|
|
||||||
// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
|
|
||||||
// r4 < 5 × 2⁵² × 2⁵²
|
|
||||||
// r4 < 2¹⁰⁷
|
|
||||||
//
|
|
||||||
|
|
||||||
c0 := shiftRightBy51(r0)
|
|
||||||
c1 := shiftRightBy51(r1)
|
|
||||||
c2 := shiftRightBy51(r2)
|
|
||||||
c3 := shiftRightBy51(r3)
|
|
||||||
c4 := shiftRightBy51(r4)
|
|
||||||
|
|
||||||
rr0 := r0.lo&maskLow51Bits + c4*19
|
|
||||||
rr1 := r1.lo&maskLow51Bits + c0
|
|
||||||
rr2 := r2.lo&maskLow51Bits + c1
|
|
||||||
rr3 := r3.lo&maskLow51Bits + c2
|
|
||||||
rr4 := r4.lo&maskLow51Bits + c3
|
|
||||||
|
|
||||||
// Now all coefficients fit into 64-bit registers but are still too large to
|
|
||||||
// be passed around as a Element. We therefore do one last carry chain,
|
|
||||||
// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
|
|
||||||
*v = Element{rr0, rr1, rr2, rr3, rr4}
|
|
||||||
v.carryPropagate()
|
|
||||||
}
|
|
||||||
|
|
||||||
func feSquareGeneric(v, a *Element) {
|
|
||||||
l0 := a.l0
|
|
||||||
l1 := a.l1
|
|
||||||
l2 := a.l2
|
|
||||||
l3 := a.l3
|
|
||||||
l4 := a.l4
|
|
||||||
|
|
||||||
// Squaring works precisely like multiplication above, but thanks to its
|
|
||||||
// symmetry we get to group a few terms together.
|
|
||||||
//
|
|
||||||
// l4 l3 l2 l1 l0 x
|
|
||||||
// l4 l3 l2 l1 l0 =
|
|
||||||
// ------------------------
|
|
||||||
// l4l0 l3l0 l2l0 l1l0 l0l0 +
|
|
||||||
// l4l1 l3l1 l2l1 l1l1 l0l1 +
|
|
||||||
// l4l2 l3l2 l2l2 l1l2 l0l2 +
|
|
||||||
// l4l3 l3l3 l2l3 l1l3 l0l3 +
|
|
||||||
// l4l4 l3l4 l2l4 l1l4 l0l4 =
|
|
||||||
// ----------------------------------------------
|
|
||||||
// r8 r7 r6 r5 r4 r3 r2 r1 r0
|
|
||||||
//
|
|
||||||
// l4l0 l3l0 l2l0 l1l0 l0l0 +
|
|
||||||
// l3l1 l2l1 l1l1 l0l1 19×l4l1 +
|
|
||||||
// l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
|
|
||||||
// l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
|
|
||||||
// l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
|
|
||||||
// --------------------------------------
|
|
||||||
// r4 r3 r2 r1 r0
|
|
||||||
//
|
|
||||||
// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
|
|
||||||
// only three Mul64 and four Add64, instead of five and eight.
|
|
||||||
|
|
||||||
l0_2 := l0 * 2
|
|
||||||
l1_2 := l1 * 2
|
|
||||||
|
|
||||||
l1_38 := l1 * 38
|
|
||||||
l2_38 := l2 * 38
|
|
||||||
l3_38 := l3 * 38
|
|
||||||
|
|
||||||
l3_19 := l3 * 19
|
|
||||||
l4_19 := l4 * 19
|
|
||||||
|
|
||||||
// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
|
|
||||||
r0 := mul64(l0, l0)
|
|
||||||
r0 = addMul64(r0, l1_38, l4)
|
|
||||||
r0 = addMul64(r0, l2_38, l3)
|
|
||||||
|
|
||||||
// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
|
|
||||||
r1 := mul64(l0_2, l1)
|
|
||||||
r1 = addMul64(r1, l2_38, l4)
|
|
||||||
r1 = addMul64(r1, l3_19, l3)
|
|
||||||
|
|
||||||
// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
|
|
||||||
r2 := mul64(l0_2, l2)
|
|
||||||
r2 = addMul64(r2, l1, l1)
|
|
||||||
r2 = addMul64(r2, l3_38, l4)
|
|
||||||
|
|
||||||
// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
|
|
||||||
r3 := mul64(l0_2, l3)
|
|
||||||
r3 = addMul64(r3, l1_2, l2)
|
|
||||||
r3 = addMul64(r3, l4_19, l4)
|
|
||||||
|
|
||||||
// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
|
|
||||||
r4 := mul64(l0_2, l4)
|
|
||||||
r4 = addMul64(r4, l1_2, l3)
|
|
||||||
r4 = addMul64(r4, l2, l2)
|
|
||||||
|
|
||||||
c0 := shiftRightBy51(r0)
|
|
||||||
c1 := shiftRightBy51(r1)
|
|
||||||
c2 := shiftRightBy51(r2)
|
|
||||||
c3 := shiftRightBy51(r3)
|
|
||||||
c4 := shiftRightBy51(r4)
|
|
||||||
|
|
||||||
rr0 := r0.lo&maskLow51Bits + c4*19
|
|
||||||
rr1 := r1.lo&maskLow51Bits + c0
|
|
||||||
rr2 := r2.lo&maskLow51Bits + c1
|
|
||||||
rr3 := r3.lo&maskLow51Bits + c2
|
|
||||||
rr4 := r4.lo&maskLow51Bits + c3
|
|
||||||
|
|
||||||
*v = Element{rr0, rr1, rr2, rr3, rr4}
|
|
||||||
v.carryPropagate()
|
|
||||||
}
|
|
||||||
|
|
||||||
// carryPropagate brings the limbs below 52 bits by applying the reduction
|
|
||||||
// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
|
|
||||||
func (v *Element) carryPropagateGeneric() *Element {
|
|
||||||
c0 := v.l0 >> 51
|
|
||||||
c1 := v.l1 >> 51
|
|
||||||
c2 := v.l2 >> 51
|
|
||||||
c3 := v.l3 >> 51
|
|
||||||
c4 := v.l4 >> 51
|
|
||||||
|
|
||||||
// c4 is at most 64 - 51 = 13 bits, so c4*19 is at most 18 bits, and
|
|
||||||
// the final l0 will be at most 52 bits. Similarly for the rest.
|
|
||||||
v.l0 = v.l0&maskLow51Bits + c4*19
|
|
||||||
v.l1 = v.l1&maskLow51Bits + c0
|
|
||||||
v.l2 = v.l2&maskLow51Bits + c1
|
|
||||||
v.l3 = v.l3&maskLow51Bits + c2
|
|
||||||
v.l4 = v.l4&maskLow51Bits + c3
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
1030
vendor/filippo.io/edwards25519/scalar.go
generated
vendored
1030
vendor/filippo.io/edwards25519/scalar.go
generated
vendored
File diff suppressed because it is too large
Load Diff
214
vendor/filippo.io/edwards25519/scalarmult.go
generated
vendored
214
vendor/filippo.io/edwards25519/scalarmult.go
generated
vendored
@ -1,214 +0,0 @@
|
|||||||
// Copyright (c) 2019 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 edwards25519
|
|
||||||
|
|
||||||
import "sync"
|
|
||||||
|
|
||||||
// basepointTable is a set of 32 affineLookupTables, where table i is generated
|
|
||||||
// from 256i * basepoint. It is precomputed the first time it's used.
|
|
||||||
func basepointTable() *[32]affineLookupTable {
|
|
||||||
basepointTablePrecomp.initOnce.Do(func() {
|
|
||||||
p := NewGeneratorPoint()
|
|
||||||
for i := 0; i < 32; i++ {
|
|
||||||
basepointTablePrecomp.table[i].FromP3(p)
|
|
||||||
for j := 0; j < 8; j++ {
|
|
||||||
p.Add(p, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return &basepointTablePrecomp.table
|
|
||||||
}
|
|
||||||
|
|
||||||
var basepointTablePrecomp struct {
|
|
||||||
table [32]affineLookupTable
|
|
||||||
initOnce sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
// ScalarBaseMult sets v = x * B, where B is the canonical generator, and
|
|
||||||
// returns v.
|
|
||||||
//
|
|
||||||
// The scalar multiplication is done in constant time.
|
|
||||||
func (v *Point) ScalarBaseMult(x *Scalar) *Point {
|
|
||||||
basepointTable := basepointTable()
|
|
||||||
|
|
||||||
// Write x = sum(x_i * 16^i) so x*B = sum( B*x_i*16^i )
|
|
||||||
// as described in the Ed25519 paper
|
|
||||||
//
|
|
||||||
// Group even and odd coefficients
|
|
||||||
// x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
|
|
||||||
// + x_1*16^1*B + x_3*16^3*B + ... + x_63*16^63*B
|
|
||||||
// x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
|
|
||||||
// + 16*( x_1*16^0*B + x_3*16^2*B + ... + x_63*16^62*B)
|
|
||||||
//
|
|
||||||
// We use a lookup table for each i to get x_i*16^(2*i)*B
|
|
||||||
// and do four doublings to multiply by 16.
|
|
||||||
digits := x.signedRadix16()
|
|
||||||
|
|
||||||
multiple := &affineCached{}
|
|
||||||
tmp1 := &projP1xP1{}
|
|
||||||
tmp2 := &projP2{}
|
|
||||||
|
|
||||||
// Accumulate the odd components first
|
|
||||||
v.Set(NewIdentityPoint())
|
|
||||||
for i := 1; i < 64; i += 2 {
|
|
||||||
basepointTable[i/2].SelectInto(multiple, digits[i])
|
|
||||||
tmp1.AddAffine(v, multiple)
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiply by 16
|
|
||||||
tmp2.FromP3(v) // tmp2 = v in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 2*v in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*v in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 4*v in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*v in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 8*v in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*v in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 16*v in P1xP1 coords
|
|
||||||
v.fromP1xP1(tmp1) // now v = 16*(odd components)
|
|
||||||
|
|
||||||
// Accumulate the even components
|
|
||||||
for i := 0; i < 64; i += 2 {
|
|
||||||
basepointTable[i/2].SelectInto(multiple, digits[i])
|
|
||||||
tmp1.AddAffine(v, multiple)
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// ScalarMult sets v = x * q, and returns v.
|
|
||||||
//
|
|
||||||
// The scalar multiplication is done in constant time.
|
|
||||||
func (v *Point) ScalarMult(x *Scalar, q *Point) *Point {
|
|
||||||
checkInitialized(q)
|
|
||||||
|
|
||||||
var table projLookupTable
|
|
||||||
table.FromP3(q)
|
|
||||||
|
|
||||||
// Write x = sum(x_i * 16^i)
|
|
||||||
// so x*Q = sum( Q*x_i*16^i )
|
|
||||||
// = Q*x_0 + 16*(Q*x_1 + 16*( ... + Q*x_63) ... )
|
|
||||||
// <------compute inside out---------
|
|
||||||
//
|
|
||||||
// We use the lookup table to get the x_i*Q values
|
|
||||||
// and do four doublings to compute 16*Q
|
|
||||||
digits := x.signedRadix16()
|
|
||||||
|
|
||||||
// Unwrap first loop iteration to save computing 16*identity
|
|
||||||
multiple := &projCached{}
|
|
||||||
tmp1 := &projP1xP1{}
|
|
||||||
tmp2 := &projP2{}
|
|
||||||
table.SelectInto(multiple, digits[63])
|
|
||||||
|
|
||||||
v.Set(NewIdentityPoint())
|
|
||||||
tmp1.Add(v, multiple) // tmp1 = x_63*Q in P1xP1 coords
|
|
||||||
for i := 62; i >= 0; i-- {
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = (prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 2*(prev) in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*(prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 4*(prev) in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*(prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 8*(prev) in P1xP1 coords
|
|
||||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*(prev) in P2 coords
|
|
||||||
tmp1.Double(tmp2) // tmp1 = 16*(prev) in P1xP1 coords
|
|
||||||
v.fromP1xP1(tmp1) // v = 16*(prev) in P3 coords
|
|
||||||
table.SelectInto(multiple, digits[i])
|
|
||||||
tmp1.Add(v, multiple) // tmp1 = x_i*Q + 16*(prev) in P1xP1 coords
|
|
||||||
}
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// basepointNafTable is the nafLookupTable8 for the basepoint.
|
|
||||||
// It is precomputed the first time it's used.
|
|
||||||
func basepointNafTable() *nafLookupTable8 {
|
|
||||||
basepointNafTablePrecomp.initOnce.Do(func() {
|
|
||||||
basepointNafTablePrecomp.table.FromP3(NewGeneratorPoint())
|
|
||||||
})
|
|
||||||
return &basepointNafTablePrecomp.table
|
|
||||||
}
|
|
||||||
|
|
||||||
var basepointNafTablePrecomp struct {
|
|
||||||
table nafLookupTable8
|
|
||||||
initOnce sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
// VarTimeDoubleScalarBaseMult sets v = a * A + b * B, where B is the canonical
|
|
||||||
// generator, and returns v.
|
|
||||||
//
|
|
||||||
// Execution time depends on the inputs.
|
|
||||||
func (v *Point) VarTimeDoubleScalarBaseMult(a *Scalar, A *Point, b *Scalar) *Point {
|
|
||||||
checkInitialized(A)
|
|
||||||
|
|
||||||
// Similarly to the single variable-base approach, we compute
|
|
||||||
// digits and use them with a lookup table. However, because
|
|
||||||
// we are allowed to do variable-time operations, we don't
|
|
||||||
// need constant-time lookups or constant-time digit
|
|
||||||
// computations.
|
|
||||||
//
|
|
||||||
// So we use a non-adjacent form of some width w instead of
|
|
||||||
// radix 16. This is like a binary representation (one digit
|
|
||||||
// for each binary place) but we allow the digits to grow in
|
|
||||||
// magnitude up to 2^{w-1} so that the nonzero digits are as
|
|
||||||
// sparse as possible. Intuitively, this "condenses" the
|
|
||||||
// "mass" of the scalar onto sparse coefficients (meaning
|
|
||||||
// fewer additions).
|
|
||||||
|
|
||||||
basepointNafTable := basepointNafTable()
|
|
||||||
var aTable nafLookupTable5
|
|
||||||
aTable.FromP3(A)
|
|
||||||
// Because the basepoint is fixed, we can use a wider NAF
|
|
||||||
// corresponding to a bigger table.
|
|
||||||
aNaf := a.nonAdjacentForm(5)
|
|
||||||
bNaf := b.nonAdjacentForm(8)
|
|
||||||
|
|
||||||
// Find the first nonzero coefficient.
|
|
||||||
i := 255
|
|
||||||
for j := i; j >= 0; j-- {
|
|
||||||
if aNaf[j] != 0 || bNaf[j] != 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
multA := &projCached{}
|
|
||||||
multB := &affineCached{}
|
|
||||||
tmp1 := &projP1xP1{}
|
|
||||||
tmp2 := &projP2{}
|
|
||||||
tmp2.Zero()
|
|
||||||
|
|
||||||
// Move from high to low bits, doubling the accumulator
|
|
||||||
// at each iteration and checking whether there is a nonzero
|
|
||||||
// coefficient to look up a multiple of.
|
|
||||||
for ; i >= 0; i-- {
|
|
||||||
tmp1.Double(tmp2)
|
|
||||||
|
|
||||||
// Only update v if we have a nonzero coeff to add in.
|
|
||||||
if aNaf[i] > 0 {
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
aTable.SelectInto(multA, aNaf[i])
|
|
||||||
tmp1.Add(v, multA)
|
|
||||||
} else if aNaf[i] < 0 {
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
aTable.SelectInto(multA, -aNaf[i])
|
|
||||||
tmp1.Sub(v, multA)
|
|
||||||
}
|
|
||||||
|
|
||||||
if bNaf[i] > 0 {
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
basepointNafTable.SelectInto(multB, bNaf[i])
|
|
||||||
tmp1.AddAffine(v, multB)
|
|
||||||
} else if bNaf[i] < 0 {
|
|
||||||
v.fromP1xP1(tmp1)
|
|
||||||
basepointNafTable.SelectInto(multB, -bNaf[i])
|
|
||||||
tmp1.SubAffine(v, multB)
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp2.FromP1xP1(tmp1)
|
|
||||||
}
|
|
||||||
|
|
||||||
v.fromP2(tmp2)
|
|
||||||
return v
|
|
||||||
}
|
|
129
vendor/filippo.io/edwards25519/tables.go
generated
vendored
129
vendor/filippo.io/edwards25519/tables.go
generated
vendored
@ -1,129 +0,0 @@
|
|||||||
// Copyright (c) 2019 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 edwards25519
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/subtle"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A dynamic lookup table for variable-base, constant-time scalar muls.
|
|
||||||
type projLookupTable struct {
|
|
||||||
points [8]projCached
|
|
||||||
}
|
|
||||||
|
|
||||||
// A precomputed lookup table for fixed-base, constant-time scalar muls.
|
|
||||||
type affineLookupTable struct {
|
|
||||||
points [8]affineCached
|
|
||||||
}
|
|
||||||
|
|
||||||
// A dynamic lookup table for variable-base, variable-time scalar muls.
|
|
||||||
type nafLookupTable5 struct {
|
|
||||||
points [8]projCached
|
|
||||||
}
|
|
||||||
|
|
||||||
// A precomputed lookup table for fixed-base, variable-time scalar muls.
|
|
||||||
type nafLookupTable8 struct {
|
|
||||||
points [64]affineCached
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructors.
|
|
||||||
|
|
||||||
// Builds a lookup table at runtime. Fast.
|
|
||||||
func (v *projLookupTable) FromP3(q *Point) {
|
|
||||||
// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
|
|
||||||
// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
|
|
||||||
v.points[0].FromP3(q)
|
|
||||||
tmpP3 := Point{}
|
|
||||||
tmpP1xP1 := projP1xP1{}
|
|
||||||
for i := 0; i < 7; i++ {
|
|
||||||
// Compute (i+1)*Q as Q + i*Q and convert to a ProjCached
|
|
||||||
// This is needlessly complicated because the API has explicit
|
|
||||||
// recievers instead of creating stack objects and relying on RVO
|
|
||||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is not optimised for speed; fixed-base tables should be precomputed.
|
|
||||||
func (v *affineLookupTable) FromP3(q *Point) {
|
|
||||||
// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
|
|
||||||
// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
|
|
||||||
v.points[0].FromP3(q)
|
|
||||||
tmpP3 := Point{}
|
|
||||||
tmpP1xP1 := projP1xP1{}
|
|
||||||
for i := 0; i < 7; i++ {
|
|
||||||
// Compute (i+1)*Q as Q + i*Q and convert to AffineCached
|
|
||||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i])))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a lookup table at runtime. Fast.
|
|
||||||
func (v *nafLookupTable5) FromP3(q *Point) {
|
|
||||||
// Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q
|
|
||||||
// This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q
|
|
||||||
v.points[0].FromP3(q)
|
|
||||||
q2 := Point{}
|
|
||||||
q2.Add(q, q)
|
|
||||||
tmpP3 := Point{}
|
|
||||||
tmpP1xP1 := projP1xP1{}
|
|
||||||
for i := 0; i < 7; i++ {
|
|
||||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(&q2, &v.points[i])))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is not optimised for speed; fixed-base tables should be precomputed.
|
|
||||||
func (v *nafLookupTable8) FromP3(q *Point) {
|
|
||||||
v.points[0].FromP3(q)
|
|
||||||
q2 := Point{}
|
|
||||||
q2.Add(q, q)
|
|
||||||
tmpP3 := Point{}
|
|
||||||
tmpP1xP1 := projP1xP1{}
|
|
||||||
for i := 0; i < 63; i++ {
|
|
||||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(&q2, &v.points[i])))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Selectors.
|
|
||||||
|
|
||||||
// Set dest to x*Q, where -8 <= x <= 8, in constant time.
|
|
||||||
func (v *projLookupTable) SelectInto(dest *projCached, x int8) {
|
|
||||||
// Compute xabs = |x|
|
|
||||||
xmask := x >> 7
|
|
||||||
xabs := uint8((x + xmask) ^ xmask)
|
|
||||||
|
|
||||||
dest.Zero()
|
|
||||||
for j := 1; j <= 8; j++ {
|
|
||||||
// Set dest = j*Q if |x| = j
|
|
||||||
cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
|
|
||||||
dest.Select(&v.points[j-1], dest, cond)
|
|
||||||
}
|
|
||||||
// Now dest = |x|*Q, conditionally negate to get x*Q
|
|
||||||
dest.CondNeg(int(xmask & 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set dest to x*Q, where -8 <= x <= 8, in constant time.
|
|
||||||
func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) {
|
|
||||||
// Compute xabs = |x|
|
|
||||||
xmask := x >> 7
|
|
||||||
xabs := uint8((x + xmask) ^ xmask)
|
|
||||||
|
|
||||||
dest.Zero()
|
|
||||||
for j := 1; j <= 8; j++ {
|
|
||||||
// Set dest = j*Q if |x| = j
|
|
||||||
cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
|
|
||||||
dest.Select(&v.points[j-1], dest, cond)
|
|
||||||
}
|
|
||||||
// Now dest = |x|*Q, conditionally negate to get x*Q
|
|
||||||
dest.CondNeg(int(xmask & 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given odd x with 0 < x < 2^4, return x*Q (in variable time).
|
|
||||||
func (v *nafLookupTable5) SelectInto(dest *projCached, x int8) {
|
|
||||||
*dest = v.points[x/2]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given odd x with 0 < x < 2^7, return x*Q (in variable time).
|
|
||||||
func (v *nafLookupTable8) SelectInto(dest *affineCached, x int8) {
|
|
||||||
*dest = v.points[x/2]
|
|
||||||
}
|
|
24
vendor/github.com/Baozisoftware/qrcode-terminal-go/.gitignore
generated
vendored
24
vendor/github.com/Baozisoftware/qrcode-terminal-go/.gitignore
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Folders
|
|
||||||
_obj
|
|
||||||
_test
|
|
||||||
|
|
||||||
# Architecture specific extensions/prefixes
|
|
||||||
*.[568vq]
|
|
||||||
[568vq].out
|
|
||||||
|
|
||||||
*.cgo1.go
|
|
||||||
*.cgo2.c
|
|
||||||
_cgo_defun.c
|
|
||||||
_cgo_gotypes.go
|
|
||||||
_cgo_export.*
|
|
||||||
|
|
||||||
_testmain.go
|
|
||||||
|
|
||||||
*.exe
|
|
||||||
*.test
|
|
||||||
*.prof
|
|
29
vendor/github.com/Baozisoftware/qrcode-terminal-go/LICENSE
generated
vendored
29
vendor/github.com/Baozisoftware/qrcode-terminal-go/LICENSE
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
BSD 3-Clause License
|
|
||||||
|
|
||||||
Copyright (c) 2017, Baozisoftware
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of the copyright holder nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
39
vendor/github.com/Baozisoftware/qrcode-terminal-go/README.md
generated
vendored
39
vendor/github.com/Baozisoftware/qrcode-terminal-go/README.md
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
|
|
||||||
# qrcode-terminal-go
|
|
||||||
QRCode terminal for golang.
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/Baozisoftware/qrcode-terminal-go"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
Test1()
|
|
||||||
Test2()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test1(){
|
|
||||||
content := "Hello, 世界"
|
|
||||||
obj := qrcodeTerminal.New()
|
|
||||||
obj.Get(content).Print()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test2(){
|
|
||||||
content := "https://github.com/Baozisoftware/qrcode-terminal-go"
|
|
||||||
obj := qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightBlue,qrcodeTerminal.ConsoleColors.BrightGreen,qrcodeTerminal.QRCodeRecoveryLevels.Low)
|
|
||||||
obj.Get([]byte(content)).Print()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
### Windows XP
|
|
||||||

|
|
||||||
### Windows 7
|
|
||||||

|
|
||||||
### Windows 10
|
|
||||||

|
|
||||||
### Ubuntu
|
|
||||||

|
|
||||||
### macOS
|
|
||||||

|
|
155
vendor/github.com/Baozisoftware/qrcode-terminal-go/qrcodeTerminal.go
generated
vendored
155
vendor/github.com/Baozisoftware/qrcode-terminal-go/qrcodeTerminal.go
generated
vendored
@ -1,155 +0,0 @@
|
|||||||
package qrcodeTerminal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/skip2/go-qrcode"
|
|
||||||
"github.com/mattn/go-colorable"
|
|
||||||
"image/png"
|
|
||||||
nbytes "bytes"
|
|
||||||
)
|
|
||||||
|
|
||||||
type consoleColor string
|
|
||||||
type consoleColors struct {
|
|
||||||
NormalBlack consoleColor
|
|
||||||
NormalRed consoleColor
|
|
||||||
NormalGreen consoleColor
|
|
||||||
NormalYellow consoleColor
|
|
||||||
NormalBlue consoleColor
|
|
||||||
NormalMagenta consoleColor
|
|
||||||
NormalCyan consoleColor
|
|
||||||
NormalWhite consoleColor
|
|
||||||
BrightBlack consoleColor
|
|
||||||
BrightRed consoleColor
|
|
||||||
BrightGreen consoleColor
|
|
||||||
BrightYellow consoleColor
|
|
||||||
BrightBlue consoleColor
|
|
||||||
BrightMagenta consoleColor
|
|
||||||
BrightCyan consoleColor
|
|
||||||
BrightWhite consoleColor
|
|
||||||
}
|
|
||||||
type qrcodeRecoveryLevel qrcode.RecoveryLevel
|
|
||||||
type qrcodeRecoveryLevels struct {
|
|
||||||
Low qrcodeRecoveryLevel
|
|
||||||
Medium qrcodeRecoveryLevel
|
|
||||||
High qrcodeRecoveryLevel
|
|
||||||
Highest qrcodeRecoveryLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ConsoleColors consoleColors = consoleColors{
|
|
||||||
NormalBlack: "\033[38;5;0m \033[0m",
|
|
||||||
NormalRed: "\033[38;5;1m \033[0m",
|
|
||||||
NormalGreen: "\033[38;5;2m \033[0m",
|
|
||||||
NormalYellow: "\033[38;5;3m \033[0m",
|
|
||||||
NormalBlue: "\033[38;5;4m \033[0m",
|
|
||||||
NormalMagenta: "\033[38;5;5m \033[0m",
|
|
||||||
NormalCyan: "\033[38;5;6m \033[0m",
|
|
||||||
NormalWhite: "\033[38;5;7m \033[0m",
|
|
||||||
BrightBlack: "\033[48;5;0m \033[0m",
|
|
||||||
BrightRed: "\033[48;5;1m \033[0m",
|
|
||||||
BrightGreen: "\033[48;5;2m \033[0m",
|
|
||||||
BrightYellow: "\033[48;5;3m \033[0m",
|
|
||||||
BrightBlue: "\033[48;5;4m \033[0m",
|
|
||||||
BrightMagenta: "\033[48;5;5m \033[0m",
|
|
||||||
BrightCyan: "\033[48;5;6m \033[0m",
|
|
||||||
BrightWhite: "\033[48;5;7m \033[0m"}
|
|
||||||
QRCodeRecoveryLevels = qrcodeRecoveryLevels{
|
|
||||||
Low: qrcodeRecoveryLevel(qrcode.Low),
|
|
||||||
Medium: qrcodeRecoveryLevel(qrcode.Medium),
|
|
||||||
High: qrcodeRecoveryLevel(qrcode.High),
|
|
||||||
Highest: qrcodeRecoveryLevel(qrcode.Highest)}
|
|
||||||
)
|
|
||||||
|
|
||||||
type QRCodeString string
|
|
||||||
|
|
||||||
func (v *QRCodeString) Print() {
|
|
||||||
fmt.Fprint(outer, *v)
|
|
||||||
}
|
|
||||||
|
|
||||||
type qrcodeTerminal struct {
|
|
||||||
front consoleColor
|
|
||||||
back consoleColor
|
|
||||||
level qrcodeRecoveryLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *qrcodeTerminal) Get(content interface{}) (result *QRCodeString) {
|
|
||||||
var qr *qrcode.QRCode
|
|
||||||
var err error
|
|
||||||
if t, ok := content.(string); ok {
|
|
||||||
qr, err = qrcode.New(t, qrcode.RecoveryLevel(v.level))
|
|
||||||
} else if t, ok := content.([]byte); ok {
|
|
||||||
qr, err = qrcode.New(string(t), qrcode.RecoveryLevel(v.level))
|
|
||||||
}
|
|
||||||
if qr != nil && err == nil {
|
|
||||||
data := qr.Bitmap()
|
|
||||||
result = v.getQRCodeString(data)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *qrcodeTerminal) Get2(bytes []byte) (result *QRCodeString) {
|
|
||||||
data, err := parseQR(bytes)
|
|
||||||
if err == nil {
|
|
||||||
result = v.getQRCodeString(data)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func New2(front, back consoleColor, level qrcodeRecoveryLevel) *qrcodeTerminal {
|
|
||||||
obj := qrcodeTerminal{front: front, back: back, level: level}
|
|
||||||
return &obj
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *qrcodeTerminal {
|
|
||||||
front, back, level := ConsoleColors.BrightBlack, ConsoleColors.BrightWhite, QRCodeRecoveryLevels.Medium
|
|
||||||
return New2(front, back, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *qrcodeTerminal) getQRCodeString(data [][]bool) (result *QRCodeString) {
|
|
||||||
str := ""
|
|
||||||
for ir, row := range data {
|
|
||||||
lr := len(row)
|
|
||||||
if ir == 0 || ir == 1 || ir == 2 ||
|
|
||||||
ir == lr-1 || ir == lr-2 || ir == lr-3 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for ic, col := range row {
|
|
||||||
lc := len(data)
|
|
||||||
if ic == 0 || ic == 1 || ic == 2 ||
|
|
||||||
ic == lc-1 || ic == lc-2 || ic == lc-3 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if col {
|
|
||||||
str += fmt.Sprint(v.front)
|
|
||||||
} else {
|
|
||||||
str += fmt.Sprint(v.back)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str += fmt.Sprintln()
|
|
||||||
}
|
|
||||||
obj := QRCodeString(str)
|
|
||||||
result = &obj
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseQR(bytes []byte) (data [][]bool, err error) {
|
|
||||||
r := nbytes.NewReader(bytes)
|
|
||||||
img, err := png.Decode(r)
|
|
||||||
if err == nil {
|
|
||||||
rect := img.Bounds()
|
|
||||||
mx, my := rect.Max.X, rect.Max.Y
|
|
||||||
data = make([][]bool, mx)
|
|
||||||
for x := 0; x < mx; x++ {
|
|
||||||
data[x] = make([]bool, my)
|
|
||||||
for y := 0; y < my; y++ {
|
|
||||||
c := img.At(x, y)
|
|
||||||
r, _, _, _ := c.RGBA()
|
|
||||||
data[x][y] = r == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var outer = colorable.NewColorableStdout()
|
|
24
vendor/github.com/Benau/go_rlottie/LICENSE
generated
vendored
24
vendor/github.com/Benau/go_rlottie/LICENSE
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2021, (see AUTHORS)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
1
vendor/github.com/Benau/go_rlottie/README.md
generated
vendored
1
vendor/github.com/Benau/go_rlottie/README.md
generated
vendored
@ -1 +0,0 @@
|
|||||||
Go binding for https://github.com/Samsung/rlottie, example at https://github.com/Benau/tgsconverter
|
|
284
vendor/github.com/Benau/go_rlottie/binding_c_lottieanimation_capi.cpp
generated
vendored
284
vendor/github.com/Benau/go_rlottie/binding_c_lottieanimation_capi.cpp
generated
vendored
@ -1,284 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "rlottie.h"
|
|
||||||
#include "rlottie_capi.h"
|
|
||||||
#include "vector_vdebug.h"
|
|
||||||
|
|
||||||
using namespace rlottie;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
struct Lottie_Animation_S
|
|
||||||
{
|
|
||||||
std::unique_ptr<Animation> mAnimation;
|
|
||||||
std::future<Surface> mRenderTask;
|
|
||||||
uint32_t *mBufferRef;
|
|
||||||
LOTMarkerList *mMarkerList;
|
|
||||||
};
|
|
||||||
|
|
||||||
RLOTTIE_API Lottie_Animation_S *lottie_animation_from_file(const char *path)
|
|
||||||
{
|
|
||||||
if (auto animation = Animation::loadFromFile(path) ) {
|
|
||||||
Lottie_Animation_S *handle = new Lottie_Animation_S();
|
|
||||||
handle->mAnimation = std::move(animation);
|
|
||||||
return handle;
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API Lottie_Animation_S *lottie_animation_from_data(const char *data, const char *key, const char *resourcePath)
|
|
||||||
{
|
|
||||||
if (auto animation = Animation::loadFromData(data, key, resourcePath) ) {
|
|
||||||
Lottie_Animation_S *handle = new Lottie_Animation_S();
|
|
||||||
handle->mAnimation = std::move(animation);
|
|
||||||
return handle;
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void lottie_animation_destroy(Lottie_Animation_S *animation)
|
|
||||||
{
|
|
||||||
if (animation) {
|
|
||||||
if (animation->mMarkerList) {
|
|
||||||
for(size_t i = 0; i < animation->mMarkerList->size; i++) {
|
|
||||||
if (animation->mMarkerList->ptr[i].name) free(animation->mMarkerList->ptr[i].name);
|
|
||||||
}
|
|
||||||
delete[] animation->mMarkerList->ptr;
|
|
||||||
delete animation->mMarkerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animation->mRenderTask.valid()) {
|
|
||||||
animation->mRenderTask.get();
|
|
||||||
}
|
|
||||||
animation->mAnimation = nullptr;
|
|
||||||
delete animation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void lottie_animation_get_size(const Lottie_Animation_S *animation, size_t *width, size_t *height)
|
|
||||||
{
|
|
||||||
if (!animation) return;
|
|
||||||
|
|
||||||
animation->mAnimation->size(*width, *height);
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API double lottie_animation_get_duration(const Lottie_Animation_S *animation)
|
|
||||||
{
|
|
||||||
if (!animation) return 0;
|
|
||||||
|
|
||||||
return animation->mAnimation->duration();
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API size_t lottie_animation_get_totalframe(const Lottie_Animation_S *animation)
|
|
||||||
{
|
|
||||||
if (!animation) return 0;
|
|
||||||
|
|
||||||
return animation->mAnimation->totalFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RLOTTIE_API double lottie_animation_get_framerate(const Lottie_Animation_S *animation)
|
|
||||||
{
|
|
||||||
if (!animation) return 0;
|
|
||||||
|
|
||||||
return animation->mAnimation->frameRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API const LOTLayerNode * lottie_animation_render_tree(Lottie_Animation_S *animation, size_t frame_num, size_t width, size_t height)
|
|
||||||
{
|
|
||||||
if (!animation) return nullptr;
|
|
||||||
|
|
||||||
return animation->mAnimation->renderTree(frame_num, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API size_t
|
|
||||||
lottie_animation_get_frame_at_pos(const Lottie_Animation_S *animation, float pos)
|
|
||||||
{
|
|
||||||
if (!animation) return 0;
|
|
||||||
|
|
||||||
return animation->mAnimation->frameAtPos(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void
|
|
||||||
lottie_animation_render(Lottie_Animation_S *animation,
|
|
||||||
size_t frame_number,
|
|
||||||
uint32_t *buffer,
|
|
||||||
size_t width,
|
|
||||||
size_t height,
|
|
||||||
size_t bytes_per_line)
|
|
||||||
{
|
|
||||||
if (!animation) return;
|
|
||||||
|
|
||||||
rlottie::Surface surface(buffer, width, height, bytes_per_line);
|
|
||||||
animation->mAnimation->renderSync(frame_number, surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void
|
|
||||||
lottie_animation_render_async(Lottie_Animation_S *animation,
|
|
||||||
size_t frame_number,
|
|
||||||
uint32_t *buffer,
|
|
||||||
size_t width,
|
|
||||||
size_t height,
|
|
||||||
size_t bytes_per_line)
|
|
||||||
{
|
|
||||||
if (!animation) return;
|
|
||||||
|
|
||||||
rlottie::Surface surface(buffer, width, height, bytes_per_line);
|
|
||||||
animation->mRenderTask = animation->mAnimation->render(frame_number, surface);
|
|
||||||
animation->mBufferRef = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API uint32_t *
|
|
||||||
lottie_animation_render_flush(Lottie_Animation_S *animation)
|
|
||||||
{
|
|
||||||
if (!animation) return nullptr;
|
|
||||||
|
|
||||||
if (animation->mRenderTask.valid()) {
|
|
||||||
animation->mRenderTask.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
return animation->mBufferRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void
|
|
||||||
lottie_animation_property_override(Lottie_Animation_S *animation,
|
|
||||||
const Lottie_Animation_Property type,
|
|
||||||
const char *keypath,
|
|
||||||
...)
|
|
||||||
{
|
|
||||||
va_list prop;
|
|
||||||
va_start(prop, keypath);
|
|
||||||
const int arg_count = [type](){
|
|
||||||
switch (type) {
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_FILLCOLOR:
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_STROKECOLOR:
|
|
||||||
return 3;
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_FILLOPACITY:
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_STROKEOPACITY:
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_STROKEWIDTH:
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_ROTATION:
|
|
||||||
return 1;
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_POSITION:
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_SCALE:
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
double v[3] = {0};
|
|
||||||
for (int i = 0; i < arg_count ; i++) {
|
|
||||||
v[i] = va_arg(prop, double);
|
|
||||||
}
|
|
||||||
va_end(prop);
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_FILLCOLOR: {
|
|
||||||
double r = v[0];
|
|
||||||
double g = v[1];
|
|
||||||
double b = v[2];
|
|
||||||
if (r > 1 || r < 0 || g > 1 || g < 0 || b > 1 || b < 0) break;
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::FillColor>(keypath, rlottie::Color(r, g, b));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_FILLOPACITY: {
|
|
||||||
double opacity = v[0];
|
|
||||||
if (opacity > 100 || opacity < 0) break;
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::FillOpacity>(keypath, (float)opacity);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_STROKECOLOR: {
|
|
||||||
double r = v[0];
|
|
||||||
double g = v[1];
|
|
||||||
double b = v[2];
|
|
||||||
if (r > 1 || r < 0 || g > 1 || g < 0 || b > 1 || b < 0) break;
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::StrokeColor>(keypath, rlottie::Color(r, g, b));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_STROKEOPACITY: {
|
|
||||||
double opacity = v[0];
|
|
||||||
if (opacity > 100 || opacity < 0) break;
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::StrokeOpacity>(keypath, (float)opacity);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_STROKEWIDTH: {
|
|
||||||
double width = v[0];
|
|
||||||
if (width < 0) break;
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::StrokeWidth>(keypath, (float)width);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_POSITION: {
|
|
||||||
double x = v[0];
|
|
||||||
double y = v[1];
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::TrPosition>(keypath, rlottie::Point((float)x, (float)y));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_SCALE: {
|
|
||||||
double w = v[0];
|
|
||||||
double h = v[1];
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::TrScale>(keypath, rlottie::Size((float)w, (float)h));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_ROTATION: {
|
|
||||||
double r = v[0];
|
|
||||||
animation->mAnimation->setValue<rlottie::Property::TrRotation>(keypath, (float)r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_ANCHOR:
|
|
||||||
case LOTTIE_ANIMATION_PROPERTY_TR_OPACITY:
|
|
||||||
//@TODO handle propery update.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API const LOTMarkerList*
|
|
||||||
lottie_animation_get_markerlist(Lottie_Animation_S *animation)
|
|
||||||
{
|
|
||||||
if (!animation) return nullptr;
|
|
||||||
|
|
||||||
auto markers = animation->mAnimation->markers();
|
|
||||||
if (markers.size() == 0) return nullptr;
|
|
||||||
if (animation->mMarkerList) return (const LOTMarkerList*)animation->mMarkerList;
|
|
||||||
|
|
||||||
animation->mMarkerList = new LOTMarkerList();
|
|
||||||
animation->mMarkerList->size = markers.size();
|
|
||||||
animation->mMarkerList->ptr = new LOTMarker[markers.size()]();
|
|
||||||
|
|
||||||
for(size_t i = 0; i < markers.size(); i++) {
|
|
||||||
animation->mMarkerList->ptr[i].name = strdup(std::get<0>(markers[i]).c_str());
|
|
||||||
animation->mMarkerList->ptr[i].startframe= std::get<1>(markers[i]);
|
|
||||||
animation->mMarkerList->ptr[i].endframe= std::get<2>(markers[i]);
|
|
||||||
}
|
|
||||||
return (const LOTMarkerList*)animation->mMarkerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void
|
|
||||||
lottie_configure_model_cache_size(size_t cacheSize)
|
|
||||||
{
|
|
||||||
rlottie::configureModelCacheSize(cacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
10
vendor/github.com/Benau/go_rlottie/config.h
generated
vendored
10
vendor/github.com/Benau/go_rlottie/config.h
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
#ifndef GO_RLOTTIE_HPP
|
|
||||||
#define GO_RLOTTIE_HPP
|
|
||||||
#ifndef __APPLE__
|
|
||||||
#ifdef __ARM_NEON__
|
|
||||||
#define USE_ARM_NEON
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#define LOTTIE_THREAD_SUPPORT
|
|
||||||
#define LOTTIE_CACHE_SUPPORT
|
|
||||||
#endif
|
|
122
vendor/github.com/Benau/go_rlottie/generate_from_rlottie.py
generated
vendored
122
vendor/github.com/Benau/go_rlottie/generate_from_rlottie.py
generated
vendored
@ -1,122 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# ./generate_from_rlottie.py /path/to/clean/rlottie/src/ /path/to/clean/rlottie/inc/
|
|
||||||
import glob
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
FILE_KEYS = {}
|
|
||||||
|
|
||||||
def get_closest_local_header(header):
|
|
||||||
for full_path, local in FILE_KEYS.items():
|
|
||||||
if os.path.basename(full_path) == header:
|
|
||||||
return local
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def fix_headers(code_text):
|
|
||||||
out = ''
|
|
||||||
has_neon = False
|
|
||||||
for line in code_text:
|
|
||||||
# Special fixes
|
|
||||||
if line == '#include <vpoint.h>':
|
|
||||||
line = '#include "vpoint.h"'
|
|
||||||
if line == '#include <vsharedptr.h>':
|
|
||||||
line = '#include "vsharedptr.h"'
|
|
||||||
if line == '#include <vglobal.h>':
|
|
||||||
line = '#include "vglobal.h"'
|
|
||||||
if line == '#include <vrect.h>':
|
|
||||||
line = '#include "vrect.h"'
|
|
||||||
# ARM on apple fixes
|
|
||||||
if '__ARM_NEON__' in line:
|
|
||||||
has_neon = True
|
|
||||||
line = line.replace('__ARM_NEON__', 'USE_ARM_NEON')
|
|
||||||
header_file = re.match('#include\s+["]([^"]+)["].*', line)
|
|
||||||
# regex to search for <, > too
|
|
||||||
#header_file = re.match('#include\s+[<"]([^>"]+)[>"].*', line)
|
|
||||||
if header_file:
|
|
||||||
header = header_file.groups()[0]
|
|
||||||
abs_header = os.path.abspath(header)
|
|
||||||
header_exists = os.path.exists(abs_header)
|
|
||||||
if header_exists and abs_header in FILE_KEYS:
|
|
||||||
out += '#include "' + FILE_KEYS[abs_header] + '"\n'
|
|
||||||
else:
|
|
||||||
local = get_closest_local_header(header)
|
|
||||||
if local != '':
|
|
||||||
out += '#include "' + local + '"\n'
|
|
||||||
else:
|
|
||||||
out += line + '\n'
|
|
||||||
else:
|
|
||||||
out += line + '\n'
|
|
||||||
if has_neon:
|
|
||||||
out = '#include "config.h"\n' + out
|
|
||||||
return out
|
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
|
||||||
print('usage: ./generate_from_rlottie.py /path/to/clean/rlottie/src/ /path/to/clean/rlottie/inc/')
|
|
||||||
os._exit(1)
|
|
||||||
|
|
||||||
code = ['.c', '.s', '.S', '.sx', 'cc', 'cpp', 'cpp' ]
|
|
||||||
header = ['.h', '.hh', '.hpp', '.hxx' ]
|
|
||||||
|
|
||||||
# Remove old files
|
|
||||||
files = os.listdir('.')
|
|
||||||
for file in files:
|
|
||||||
if file.endswith(tuple(code)) or file.endswith(tuple(header)):
|
|
||||||
os.remove(os.path.join('.', file))
|
|
||||||
|
|
||||||
paths = []
|
|
||||||
it = iter(sys.argv)
|
|
||||||
next(it, None)
|
|
||||||
for argv in it:
|
|
||||||
paths.append(argv)
|
|
||||||
|
|
||||||
for path in paths:
|
|
||||||
for file in glob.iglob(path + '/**', recursive=True):
|
|
||||||
# Ignore msvc config.h and wasm file
|
|
||||||
if file.endswith('config.h') or 'wasm' in file:
|
|
||||||
continue
|
|
||||||
if file.endswith(tuple(code)) or file.endswith(tuple(header)):
|
|
||||||
key = os.path.abspath(file)
|
|
||||||
val = file.replace(path, '').replace('/', '_')
|
|
||||||
FILE_KEYS[key] = val
|
|
||||||
|
|
||||||
header_check = []
|
|
||||||
for full_path, local in FILE_KEYS.items():
|
|
||||||
header_file = os.path.basename(full_path)
|
|
||||||
if header_file.endswith(tuple(code)):
|
|
||||||
continue
|
|
||||||
if not header_file in header_check:
|
|
||||||
header_check.append(header_file)
|
|
||||||
else:
|
|
||||||
print('WARNING: ' + header_file + ' has multiple reference in subdirectories')
|
|
||||||
|
|
||||||
cur_dir = os.path.abspath('.')
|
|
||||||
for full_path, local in FILE_KEYS.items():
|
|
||||||
os.chdir(os.path.dirname(full_path))
|
|
||||||
with open(full_path) as code:
|
|
||||||
code_text = code.read().splitlines()
|
|
||||||
code.close()
|
|
||||||
fixed = fix_headers(code_text)
|
|
||||||
os.chdir(cur_dir)
|
|
||||||
local_file = open(local, "w")
|
|
||||||
local_file.write(fixed)
|
|
||||||
local_file.close()
|
|
||||||
|
|
||||||
# Write config.h
|
|
||||||
config = '#ifndef GO_RLOTTIE_HPP\n#define GO_RLOTTIE_HPP\n'
|
|
||||||
# ARM on apple won't compile
|
|
||||||
config += '#ifndef __APPLE__\n#ifdef __ARM_NEON__\n#define USE_ARM_NEON\n#endif\n#endif\n'
|
|
||||||
config += '#define LOTTIE_THREAD_SUPPORT\n#define LOTTIE_CACHE_SUPPORT\n'
|
|
||||||
config += '#endif\n'
|
|
||||||
config_file = open('config.h', "w")
|
|
||||||
config_file.write(config)
|
|
||||||
config_file.close()
|
|
||||||
|
|
||||||
# Fix vector_pixman_pixman-arm-neon-asm.S
|
|
||||||
with open('vector_pixman_pixman-arm-neon-asm.S') as code:
|
|
||||||
assembly = code.read()
|
|
||||||
code.close()
|
|
||||||
assembly = '#include "config.h"\n#ifdef USE_ARM_NEON\n' + assembly + '#endif\n'
|
|
||||||
fixed_assembly = open('vector_pixman_pixman-arm-neon-asm.S', "w")
|
|
||||||
fixed_assembly.write(assembly)
|
|
||||||
fixed_assembly.close()
|
|
56
vendor/github.com/Benau/go_rlottie/go_rlottie.go
generated
vendored
56
vendor/github.com/Benau/go_rlottie/go_rlottie.go
generated
vendored
@ -1,56 +0,0 @@
|
|||||||
package go_rlottie
|
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo !windows LDFLAGS: -lm
|
|
||||||
#cgo windows CFLAGS: -DRLOTTIE_BUILD=0
|
|
||||||
#cgo windows CXXFLAGS: -DRLOTTIE_BUILD=0
|
|
||||||
#cgo CXXFLAGS: -std=c++14 -fno-exceptions -fno-asynchronous-unwind-tables -fno-rtti -Wall -fvisibility=hidden -Wnon-virtual-dtor -Woverloaded-virtual -Wno-unused-parameter
|
|
||||||
#include "rlottie_capi.h"
|
|
||||||
void lottie_configure_model_cache_size(size_t cacheSize);
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
type Lottie_Animation *C.Lottie_Animation
|
|
||||||
|
|
||||||
func LottieConfigureModelCacheSize(size uint) {
|
|
||||||
C.lottie_configure_model_cache_size(C.size_t(size))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationFromData(data string, key string, resource_path string) Lottie_Animation {
|
|
||||||
var animation Lottie_Animation
|
|
||||||
animation = C.lottie_animation_from_data(C.CString(data), C.CString(key), C.CString(resource_path))
|
|
||||||
return animation
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationDestroy(animation Lottie_Animation) {
|
|
||||||
C.lottie_animation_destroy(animation)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationGetSize(animation Lottie_Animation) (uint, uint) {
|
|
||||||
var width C.size_t
|
|
||||||
var height C.size_t
|
|
||||||
C.lottie_animation_get_size(animation, &width, &height)
|
|
||||||
return uint(width), uint(height)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationGetTotalframe(animation Lottie_Animation) uint {
|
|
||||||
return uint(C.lottie_animation_get_totalframe(animation))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationGetFramerate(animation Lottie_Animation) float64 {
|
|
||||||
return float64(C.lottie_animation_get_framerate(animation))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationGetFrameAtPos(animation Lottie_Animation, pos float32) uint {
|
|
||||||
return uint(C.lottie_animation_get_frame_at_pos(animation, C.float(pos)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationGetDuration(animation Lottie_Animation) float64 {
|
|
||||||
return float64(C.lottie_animation_get_duration(animation))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LottieAnimationRender(animation Lottie_Animation, frame_num uint, buffer []byte, width uint, height uint, bytes_per_line uint) {
|
|
||||||
var ptr *C.uint32_t = (*C.uint32_t)(unsafe.Pointer(&buffer[0]));
|
|
||||||
C.lottie_animation_render(animation, C.size_t(frame_num), ptr, C.size_t(width), C.size_t(height), C.size_t(bytes_per_line))
|
|
||||||
}
|
|
457
vendor/github.com/Benau/go_rlottie/lottie_lottieanimation.cpp
generated
vendored
457
vendor/github.com/Benau/go_rlottie/lottie_lottieanimation.cpp
generated
vendored
@ -1,457 +0,0 @@
|
|||||||
#include "config.h"
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "config.h"
|
|
||||||
#include "lottie_lottieitem.h"
|
|
||||||
#include "lottie_lottiemodel.h"
|
|
||||||
#include "rlottie.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
using namespace rlottie;
|
|
||||||
using namespace rlottie::internal;
|
|
||||||
|
|
||||||
RLOTTIE_API void rlottie::configureModelCacheSize(size_t cacheSize)
|
|
||||||
{
|
|
||||||
internal::model::configureModelCacheSize(cacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RenderTask {
|
|
||||||
RenderTask() { receiver = sender.get_future(); }
|
|
||||||
std::promise<Surface> sender;
|
|
||||||
std::future<Surface> receiver;
|
|
||||||
AnimationImpl * playerImpl{nullptr};
|
|
||||||
size_t frameNo{0};
|
|
||||||
Surface surface;
|
|
||||||
bool keepAspectRatio{true};
|
|
||||||
};
|
|
||||||
using SharedRenderTask = std::shared_ptr<RenderTask>;
|
|
||||||
|
|
||||||
class AnimationImpl {
|
|
||||||
public:
|
|
||||||
void init(std::shared_ptr<model::Composition> composition);
|
|
||||||
bool update(size_t frameNo, const VSize &size, bool keepAspectRatio);
|
|
||||||
VSize size() const { return mModel->size(); }
|
|
||||||
double duration() const { return mModel->duration(); }
|
|
||||||
double frameRate() const { return mModel->frameRate(); }
|
|
||||||
size_t totalFrame() const { return mModel->totalFrame(); }
|
|
||||||
size_t frameAtPos(double pos) const { return mModel->frameAtPos(pos); }
|
|
||||||
Surface render(size_t frameNo, const Surface &surface,
|
|
||||||
bool keepAspectRatio);
|
|
||||||
std::future<Surface> renderAsync(size_t frameNo, Surface &&surface,
|
|
||||||
bool keepAspectRatio);
|
|
||||||
const LOTLayerNode * renderTree(size_t frameNo, const VSize &size);
|
|
||||||
|
|
||||||
const LayerInfoList &layerInfoList() const
|
|
||||||
{
|
|
||||||
if (mLayerList.empty()) {
|
|
||||||
mLayerList = mModel->layerInfoList();
|
|
||||||
}
|
|
||||||
return mLayerList;
|
|
||||||
}
|
|
||||||
const MarkerList &markers() const { return mModel->markers(); }
|
|
||||||
void setValue(const std::string &keypath, LOTVariant &&value);
|
|
||||||
void removeFilter(const std::string &keypath, Property prop);
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable LayerInfoList mLayerList;
|
|
||||||
model::Composition * mModel;
|
|
||||||
SharedRenderTask mTask;
|
|
||||||
std::atomic<bool> mRenderInProgress;
|
|
||||||
std::unique_ptr<renderer::Composition> mRenderer{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
void AnimationImpl::setValue(const std::string &keypath, LOTVariant &&value)
|
|
||||||
{
|
|
||||||
if (keypath.empty()) return;
|
|
||||||
mRenderer->setValue(keypath, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const LOTLayerNode *AnimationImpl::renderTree(size_t frameNo, const VSize &size)
|
|
||||||
{
|
|
||||||
if (update(frameNo, size, true)) {
|
|
||||||
mRenderer->buildRenderTree();
|
|
||||||
}
|
|
||||||
return mRenderer->renderTree();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AnimationImpl::update(size_t frameNo, const VSize &size,
|
|
||||||
bool keepAspectRatio)
|
|
||||||
{
|
|
||||||
frameNo += mModel->startFrame();
|
|
||||||
|
|
||||||
if (frameNo > mModel->endFrame()) frameNo = mModel->endFrame();
|
|
||||||
|
|
||||||
if (frameNo < mModel->startFrame()) frameNo = mModel->startFrame();
|
|
||||||
|
|
||||||
return mRenderer->update(int(frameNo), size, keepAspectRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
Surface AnimationImpl::render(size_t frameNo, const Surface &surface,
|
|
||||||
bool keepAspectRatio)
|
|
||||||
{
|
|
||||||
bool renderInProgress = mRenderInProgress.load();
|
|
||||||
if (renderInProgress) {
|
|
||||||
vCritical << "Already Rendering Scheduled for this Animation";
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
mRenderInProgress.store(true);
|
|
||||||
update(
|
|
||||||
frameNo,
|
|
||||||
VSize(int(surface.drawRegionWidth()), int(surface.drawRegionHeight())),
|
|
||||||
keepAspectRatio);
|
|
||||||
mRenderer->render(surface);
|
|
||||||
mRenderInProgress.store(false);
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimationImpl::init(std::shared_ptr<model::Composition> composition)
|
|
||||||
{
|
|
||||||
mModel = composition.get();
|
|
||||||
mRenderer = std::make_unique<renderer::Composition>(composition);
|
|
||||||
mRenderInProgress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LOTTIE_THREAD_SUPPORT
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include "vector_vtaskqueue.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implement a task stealing schduler to perform render task
|
|
||||||
* As each player draws into its own buffer we can delegate this
|
|
||||||
* task to a slave thread. The scheduler creates a threadpool depending
|
|
||||||
* on the number of cores available in the system and does a simple fair
|
|
||||||
* scheduling by assigning the task in a round-robin fashion. Each thread
|
|
||||||
* in the threadpool has its own queue. once it finishes all the task on its
|
|
||||||
* own queue it goes through rest of the queue and looks for task if it founds
|
|
||||||
* one it steals the task from it and executes. if it couldn't find one then it
|
|
||||||
* just waits for new task on its own queue.
|
|
||||||
*/
|
|
||||||
class RenderTaskScheduler {
|
|
||||||
const unsigned _count{std::thread::hardware_concurrency()};
|
|
||||||
std::vector<std::thread> _threads;
|
|
||||||
std::vector<TaskQueue<SharedRenderTask>> _q{_count};
|
|
||||||
std::atomic<unsigned> _index{0};
|
|
||||||
|
|
||||||
void run(unsigned i)
|
|
||||||
{
|
|
||||||
while (true) {
|
|
||||||
bool success = false;
|
|
||||||
SharedRenderTask task;
|
|
||||||
for (unsigned n = 0; n != _count * 2; ++n) {
|
|
||||||
if (_q[(i + n) % _count].try_pop(task)) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!success && !_q[i].pop(task)) break;
|
|
||||||
|
|
||||||
auto result = task->playerImpl->render(task->frameNo, task->surface,
|
|
||||||
task->keepAspectRatio);
|
|
||||||
task->sender.set_value(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderTaskScheduler()
|
|
||||||
{
|
|
||||||
for (unsigned n = 0; n != _count; ++n) {
|
|
||||||
_threads.emplace_back([&, n] { run(n); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static RenderTaskScheduler &instance()
|
|
||||||
{
|
|
||||||
static RenderTaskScheduler singleton;
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
~RenderTaskScheduler()
|
|
||||||
{
|
|
||||||
for (auto &e : _q) e.done();
|
|
||||||
|
|
||||||
for (auto &e : _threads) e.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::future<Surface> process(SharedRenderTask task)
|
|
||||||
{
|
|
||||||
auto receiver = std::move(task->receiver);
|
|
||||||
auto i = _index++;
|
|
||||||
|
|
||||||
for (unsigned n = 0; n != _count; ++n) {
|
|
||||||
if (_q[(i + n) % _count].try_push(std::move(task))) return receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_count > 0) {
|
|
||||||
_q[i % _count].push(std::move(task));
|
|
||||||
}
|
|
||||||
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
class RenderTaskScheduler {
|
|
||||||
public:
|
|
||||||
static RenderTaskScheduler &instance()
|
|
||||||
{
|
|
||||||
static RenderTaskScheduler singleton;
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::future<Surface> process(SharedRenderTask task)
|
|
||||||
{
|
|
||||||
auto result = task->playerImpl->render(task->frameNo, task->surface,
|
|
||||||
task->keepAspectRatio);
|
|
||||||
task->sender.set_value(result);
|
|
||||||
return std::move(task->receiver);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::future<Surface> AnimationImpl::renderAsync(size_t frameNo,
|
|
||||||
Surface &&surface,
|
|
||||||
bool keepAspectRatio)
|
|
||||||
{
|
|
||||||
if (!mTask) {
|
|
||||||
mTask = std::make_shared<RenderTask>();
|
|
||||||
} else {
|
|
||||||
mTask->sender = std::promise<Surface>();
|
|
||||||
mTask->receiver = mTask->sender.get_future();
|
|
||||||
}
|
|
||||||
mTask->playerImpl = this;
|
|
||||||
mTask->frameNo = frameNo;
|
|
||||||
mTask->surface = std::move(surface);
|
|
||||||
mTask->keepAspectRatio = keepAspectRatio;
|
|
||||||
|
|
||||||
return RenderTaskScheduler::instance().process(mTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \breif Brief abput the Api.
|
|
||||||
* Description about the setFilePath Api
|
|
||||||
* @param path add the details
|
|
||||||
*/
|
|
||||||
std::unique_ptr<Animation> Animation::loadFromData(
|
|
||||||
std::string jsonData, const std::string &key,
|
|
||||||
const std::string &resourcePath, bool cachePolicy)
|
|
||||||
{
|
|
||||||
if (jsonData.empty()) {
|
|
||||||
vWarning << "jason data is empty";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto composition = model::loadFromData(std::move(jsonData), key,
|
|
||||||
resourcePath, cachePolicy);
|
|
||||||
if (composition) {
|
|
||||||
auto animation = std::unique_ptr<Animation>(new Animation);
|
|
||||||
animation->d->init(std::move(composition));
|
|
||||||
return animation;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Animation> Animation::loadFromData(std::string jsonData,
|
|
||||||
std::string resourcePath,
|
|
||||||
ColorFilter filter)
|
|
||||||
{
|
|
||||||
if (jsonData.empty()) {
|
|
||||||
vWarning << "jason data is empty";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto composition = model::loadFromData(
|
|
||||||
std::move(jsonData), std::move(resourcePath), std::move(filter));
|
|
||||||
if (composition) {
|
|
||||||
auto animation = std::unique_ptr<Animation>(new Animation);
|
|
||||||
animation->d->init(std::move(composition));
|
|
||||||
return animation;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Animation> Animation::loadFromFile(const std::string &path,
|
|
||||||
bool cachePolicy)
|
|
||||||
{
|
|
||||||
if (path.empty()) {
|
|
||||||
vWarning << "File path is empty";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto composition = model::loadFromFile(path, cachePolicy);
|
|
||||||
if (composition) {
|
|
||||||
auto animation = std::unique_ptr<Animation>(new Animation);
|
|
||||||
animation->d->init(std::move(composition));
|
|
||||||
return animation;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::size(size_t &width, size_t &height) const
|
|
||||||
{
|
|
||||||
VSize sz = d->size();
|
|
||||||
|
|
||||||
width = sz.width();
|
|
||||||
height = sz.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
double Animation::duration() const
|
|
||||||
{
|
|
||||||
return d->duration();
|
|
||||||
}
|
|
||||||
|
|
||||||
double Animation::frameRate() const
|
|
||||||
{
|
|
||||||
return d->frameRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Animation::totalFrame() const
|
|
||||||
{
|
|
||||||
return d->totalFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Animation::frameAtPos(double pos)
|
|
||||||
{
|
|
||||||
return d->frameAtPos(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
const LOTLayerNode *Animation::renderTree(size_t frameNo, size_t width,
|
|
||||||
size_t height) const
|
|
||||||
{
|
|
||||||
return d->renderTree(frameNo, VSize(int(width), int(height)));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::future<Surface> Animation::render(size_t frameNo, Surface surface,
|
|
||||||
bool keepAspectRatio)
|
|
||||||
{
|
|
||||||
return d->renderAsync(frameNo, std::move(surface), keepAspectRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::renderSync(size_t frameNo, Surface surface,
|
|
||||||
bool keepAspectRatio)
|
|
||||||
{
|
|
||||||
d->render(frameNo, surface, keepAspectRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
const LayerInfoList &Animation::layers() const
|
|
||||||
{
|
|
||||||
return d->layerInfoList();
|
|
||||||
}
|
|
||||||
|
|
||||||
const MarkerList &Animation::markers() const
|
|
||||||
{
|
|
||||||
return d->markers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Color_Type, Property prop, const std::string &keypath,
|
|
||||||
Color value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath,
|
|
||||||
LOTVariant(prop, [value](const FrameInfo &) { return value; }));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Float_Type, Property prop, const std::string &keypath,
|
|
||||||
float value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath,
|
|
||||||
LOTVariant(prop, [value](const FrameInfo &) { return value; }));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Size_Type, Property prop, const std::string &keypath,
|
|
||||||
Size value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath,
|
|
||||||
LOTVariant(prop, [value](const FrameInfo &) { return value; }));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Point_Type, Property prop, const std::string &keypath,
|
|
||||||
Point value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath,
|
|
||||||
LOTVariant(prop, [value](const FrameInfo &) { return value; }));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Color_Type, Property prop, const std::string &keypath,
|
|
||||||
std::function<Color(const FrameInfo &)> &&value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath, LOTVariant(prop, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Float_Type, Property prop, const std::string &keypath,
|
|
||||||
std::function<float(const FrameInfo &)> &&value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath, LOTVariant(prop, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Size_Type, Property prop, const std::string &keypath,
|
|
||||||
std::function<Size(const FrameInfo &)> &&value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath, LOTVariant(prop, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::setValue(Point_Type, Property prop, const std::string &keypath,
|
|
||||||
std::function<Point(const FrameInfo &)> &&value)
|
|
||||||
{
|
|
||||||
d->setValue(keypath, LOTVariant(prop, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
Animation::~Animation() = default;
|
|
||||||
Animation::Animation() : d(std::make_unique<AnimationImpl>()) {}
|
|
||||||
|
|
||||||
Surface::Surface(uint32_t *buffer, size_t width, size_t height,
|
|
||||||
size_t bytesPerLine)
|
|
||||||
: mBuffer(buffer),
|
|
||||||
mWidth(width),
|
|
||||||
mHeight(height),
|
|
||||||
mBytesPerLine(bytesPerLine)
|
|
||||||
{
|
|
||||||
mDrawArea.w = mWidth;
|
|
||||||
mDrawArea.h = mHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Surface::setDrawRegion(size_t x, size_t y, size_t width, size_t height)
|
|
||||||
{
|
|
||||||
if ((x + width > mWidth) || (y + height > mHeight)) return;
|
|
||||||
|
|
||||||
mDrawArea.x = x;
|
|
||||||
mDrawArea.y = y;
|
|
||||||
mDrawArea.w = width;
|
|
||||||
mDrawArea.h = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LOTTIE_LOGGING_SUPPORT
|
|
||||||
void initLogging()
|
|
||||||
{
|
|
||||||
#if defined(USE_ARM_NEON)
|
|
||||||
set_log_level(LogLevel::OFF);
|
|
||||||
#else
|
|
||||||
initialize(GuaranteedLogger(), "/tmp/", "rlottie", 1);
|
|
||||||
set_log_level(LogLevel::INFO);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
V_CONSTRUCTOR_FUNCTION(initLogging)
|
|
||||||
#endif
|
|
435
vendor/github.com/Benau/go_rlottie/lottie_lottiefiltermodel.h
generated
vendored
435
vendor/github.com/Benau/go_rlottie/lottie_lottiefiltermodel.h
generated
vendored
@ -1,435 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LOTTIEFILTERMODEL_H
|
|
||||||
#define LOTTIEFILTERMODEL_H
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <bitset>
|
|
||||||
#include <cassert>
|
|
||||||
#include "lottie_lottiemodel.h"
|
|
||||||
#include "rlottie.h"
|
|
||||||
|
|
||||||
using namespace rlottie::internal;
|
|
||||||
// Naive way to implement std::variant
|
|
||||||
// refactor it when we move to c++17
|
|
||||||
// users should make sure proper combination
|
|
||||||
// of id and value are passed while creating the object.
|
|
||||||
class LOTVariant {
|
|
||||||
public:
|
|
||||||
using ValueFunc = std::function<float(const rlottie::FrameInfo&)>;
|
|
||||||
using ColorFunc = std::function<rlottie::Color(const rlottie::FrameInfo&)>;
|
|
||||||
using PointFunc = std::function<rlottie::Point(const rlottie::FrameInfo&)>;
|
|
||||||
using SizeFunc = std::function<rlottie::Size(const rlottie::FrameInfo&)>;
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, const ValueFunc& v)
|
|
||||||
: mPropery(prop), mTag(Value)
|
|
||||||
{
|
|
||||||
construct(impl.valueFunc, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, ValueFunc&& v)
|
|
||||||
: mPropery(prop), mTag(Value)
|
|
||||||
{
|
|
||||||
moveConstruct(impl.valueFunc, std::move(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, const ColorFunc& v)
|
|
||||||
: mPropery(prop), mTag(Color)
|
|
||||||
{
|
|
||||||
construct(impl.colorFunc, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, ColorFunc&& v)
|
|
||||||
: mPropery(prop), mTag(Color)
|
|
||||||
{
|
|
||||||
moveConstruct(impl.colorFunc, std::move(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, const PointFunc& v)
|
|
||||||
: mPropery(prop), mTag(Point)
|
|
||||||
{
|
|
||||||
construct(impl.pointFunc, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, PointFunc&& v)
|
|
||||||
: mPropery(prop), mTag(Point)
|
|
||||||
{
|
|
||||||
moveConstruct(impl.pointFunc, std::move(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, const SizeFunc& v)
|
|
||||||
: mPropery(prop), mTag(Size)
|
|
||||||
{
|
|
||||||
construct(impl.sizeFunc, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant(rlottie::Property prop, SizeFunc&& v)
|
|
||||||
: mPropery(prop), mTag(Size)
|
|
||||||
{
|
|
||||||
moveConstruct(impl.sizeFunc, std::move(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
rlottie::Property property() const { return mPropery; }
|
|
||||||
|
|
||||||
const ColorFunc& color() const
|
|
||||||
{
|
|
||||||
assert(mTag == Color);
|
|
||||||
return impl.colorFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ValueFunc& value() const
|
|
||||||
{
|
|
||||||
assert(mTag == Value);
|
|
||||||
return impl.valueFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PointFunc& point() const
|
|
||||||
{
|
|
||||||
assert(mTag == Point);
|
|
||||||
return impl.pointFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SizeFunc& size() const
|
|
||||||
{
|
|
||||||
assert(mTag == Size);
|
|
||||||
return impl.sizeFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTVariant() = default;
|
|
||||||
~LOTVariant() noexcept { Destroy(); }
|
|
||||||
LOTVariant(const LOTVariant& other) { Copy(other); }
|
|
||||||
LOTVariant(LOTVariant&& other) noexcept { Move(std::move(other)); }
|
|
||||||
LOTVariant& operator=(LOTVariant&& other)
|
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
Move(std::move(other));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
LOTVariant& operator=(const LOTVariant& other)
|
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
Copy(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
void construct(T& member, const T& val)
|
|
||||||
{
|
|
||||||
new (&member) T(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void moveConstruct(T& member, T&& val)
|
|
||||||
{
|
|
||||||
new (&member) T(std::move(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Move(LOTVariant&& other)
|
|
||||||
{
|
|
||||||
switch (other.mTag) {
|
|
||||||
case Type::Value:
|
|
||||||
moveConstruct(impl.valueFunc, std::move(other.impl.valueFunc));
|
|
||||||
break;
|
|
||||||
case Type::Color:
|
|
||||||
moveConstruct(impl.colorFunc, std::move(other.impl.colorFunc));
|
|
||||||
break;
|
|
||||||
case Type::Point:
|
|
||||||
moveConstruct(impl.pointFunc, std::move(other.impl.pointFunc));
|
|
||||||
break;
|
|
||||||
case Type::Size:
|
|
||||||
moveConstruct(impl.sizeFunc, std::move(other.impl.sizeFunc));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mTag = other.mTag;
|
|
||||||
mPropery = other.mPropery;
|
|
||||||
other.mTag = MonoState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Copy(const LOTVariant& other)
|
|
||||||
{
|
|
||||||
switch (other.mTag) {
|
|
||||||
case Type::Value:
|
|
||||||
construct(impl.valueFunc, other.impl.valueFunc);
|
|
||||||
break;
|
|
||||||
case Type::Color:
|
|
||||||
construct(impl.colorFunc, other.impl.colorFunc);
|
|
||||||
break;
|
|
||||||
case Type::Point:
|
|
||||||
construct(impl.pointFunc, other.impl.pointFunc);
|
|
||||||
break;
|
|
||||||
case Type::Size:
|
|
||||||
construct(impl.sizeFunc, other.impl.sizeFunc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mTag = other.mTag;
|
|
||||||
mPropery = other.mPropery;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Destroy()
|
|
||||||
{
|
|
||||||
switch (mTag) {
|
|
||||||
case MonoState: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Value: {
|
|
||||||
impl.valueFunc.~ValueFunc();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Color: {
|
|
||||||
impl.colorFunc.~ColorFunc();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Point: {
|
|
||||||
impl.pointFunc.~PointFunc();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Size: {
|
|
||||||
impl.sizeFunc.~SizeFunc();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Type { MonoState, Value, Color, Point, Size };
|
|
||||||
rlottie::Property mPropery;
|
|
||||||
Type mTag{MonoState};
|
|
||||||
union details {
|
|
||||||
ColorFunc colorFunc;
|
|
||||||
ValueFunc valueFunc;
|
|
||||||
PointFunc pointFunc;
|
|
||||||
SizeFunc sizeFunc;
|
|
||||||
details() {}
|
|
||||||
~details() noexcept {}
|
|
||||||
} impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace rlottie {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
namespace model {
|
|
||||||
|
|
||||||
class FilterData {
|
|
||||||
public:
|
|
||||||
void addValue(LOTVariant& value)
|
|
||||||
{
|
|
||||||
uint index = static_cast<uint>(value.property());
|
|
||||||
if (mBitset.test(index)) {
|
|
||||||
std::replace_if(mFilters.begin(), mFilters.end(),
|
|
||||||
[&value](const LOTVariant& e) {
|
|
||||||
return e.property() == value.property();
|
|
||||||
},
|
|
||||||
value);
|
|
||||||
} else {
|
|
||||||
mBitset.set(index);
|
|
||||||
mFilters.push_back(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeValue(LOTVariant& value)
|
|
||||||
{
|
|
||||||
uint index = static_cast<uint>(value.property());
|
|
||||||
if (mBitset.test(index)) {
|
|
||||||
mBitset.reset(index);
|
|
||||||
mFilters.erase(std::remove_if(mFilters.begin(), mFilters.end(),
|
|
||||||
[&value](const LOTVariant& e) {
|
|
||||||
return e.property() ==
|
|
||||||
value.property();
|
|
||||||
}),
|
|
||||||
mFilters.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool hasFilter(rlottie::Property prop) const
|
|
||||||
{
|
|
||||||
return mBitset.test(static_cast<uint>(prop));
|
|
||||||
}
|
|
||||||
model::Color color(rlottie::Property prop, int frame) const
|
|
||||||
{
|
|
||||||
rlottie::FrameInfo info(frame);
|
|
||||||
rlottie::Color col = data(prop).color()(info);
|
|
||||||
return model::Color(col.r(), col.g(), col.b());
|
|
||||||
}
|
|
||||||
VPointF point(rlottie::Property prop, int frame) const
|
|
||||||
{
|
|
||||||
rlottie::FrameInfo info(frame);
|
|
||||||
rlottie::Point pt = data(prop).point()(info);
|
|
||||||
return VPointF(pt.x(), pt.y());
|
|
||||||
}
|
|
||||||
VSize scale(rlottie::Property prop, int frame) const
|
|
||||||
{
|
|
||||||
rlottie::FrameInfo info(frame);
|
|
||||||
rlottie::Size sz = data(prop).size()(info);
|
|
||||||
return VSize(sz.w(), sz.h());
|
|
||||||
}
|
|
||||||
float opacity(rlottie::Property prop, int frame) const
|
|
||||||
{
|
|
||||||
rlottie::FrameInfo info(frame);
|
|
||||||
float val = data(prop).value()(info);
|
|
||||||
return val / 100;
|
|
||||||
}
|
|
||||||
float value(rlottie::Property prop, int frame) const
|
|
||||||
{
|
|
||||||
rlottie::FrameInfo info(frame);
|
|
||||||
return data(prop).value()(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const LOTVariant& data(rlottie::Property prop) const
|
|
||||||
{
|
|
||||||
auto result = std::find_if(
|
|
||||||
mFilters.begin(), mFilters.end(),
|
|
||||||
[prop](const LOTVariant& e) { return e.property() == prop; });
|
|
||||||
return *result;
|
|
||||||
}
|
|
||||||
std::bitset<32> mBitset{0};
|
|
||||||
std::vector<LOTVariant> mFilters;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct FilterBase
|
|
||||||
{
|
|
||||||
FilterBase(T *model): model_(model){}
|
|
||||||
|
|
||||||
const char* name() const { return model_->name(); }
|
|
||||||
|
|
||||||
FilterData* filter() {
|
|
||||||
if (!filterData_) filterData_ = std::make_unique<FilterData>();
|
|
||||||
return filterData_.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
const FilterData * filter() const { return filterData_.get(); }
|
|
||||||
const T* model() const { return model_;}
|
|
||||||
|
|
||||||
bool hasFilter(rlottie::Property prop) const {
|
|
||||||
return filterData_ ? filterData_->hasFilter(prop)
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* model_{nullptr};
|
|
||||||
std::unique_ptr<FilterData> filterData_{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Filter : public FilterBase<T> {
|
|
||||||
public:
|
|
||||||
Filter(T* model): FilterBase<T>(model){}
|
|
||||||
model::Color color(int frame) const
|
|
||||||
{
|
|
||||||
if (this->hasFilter(rlottie::Property::StrokeColor)) {
|
|
||||||
return this->filter()->color(rlottie::Property::StrokeColor, frame);
|
|
||||||
}
|
|
||||||
return this->model()->color(frame);
|
|
||||||
}
|
|
||||||
float opacity(int frame) const
|
|
||||||
{
|
|
||||||
if (this->hasFilter(rlottie::Property::StrokeOpacity)) {
|
|
||||||
return this->filter()->opacity(rlottie::Property::StrokeOpacity, frame);
|
|
||||||
}
|
|
||||||
return this->model()->opacity(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
float strokeWidth(int frame) const
|
|
||||||
{
|
|
||||||
if (this->hasFilter(rlottie::Property::StrokeWidth)) {
|
|
||||||
return this->filter()->value(rlottie::Property::StrokeWidth, frame);
|
|
||||||
}
|
|
||||||
return this->model()->strokeWidth(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
float miterLimit() const { return this->model()->miterLimit(); }
|
|
||||||
CapStyle capStyle() const { return this->model()->capStyle(); }
|
|
||||||
JoinStyle joinStyle() const { return this->model()->joinStyle(); }
|
|
||||||
bool hasDashInfo() const { return this->model()->hasDashInfo(); }
|
|
||||||
void getDashInfo(int frameNo, std::vector<float>& result) const
|
|
||||||
{
|
|
||||||
return this->model()->getDashInfo(frameNo, result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class Filter<model::Fill>: public FilterBase<model::Fill>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Filter(model::Fill* model) : FilterBase<model::Fill>(model) {}
|
|
||||||
|
|
||||||
model::Color color(int frame) const
|
|
||||||
{
|
|
||||||
if (this->hasFilter(rlottie::Property::FillColor)) {
|
|
||||||
return this->filter()->color(rlottie::Property::FillColor, frame);
|
|
||||||
}
|
|
||||||
return this->model()->color(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
float opacity(int frame) const
|
|
||||||
{
|
|
||||||
if (this->hasFilter(rlottie::Property::FillOpacity)) {
|
|
||||||
return this->filter()->opacity(rlottie::Property::FillOpacity, frame);
|
|
||||||
}
|
|
||||||
return this->model()->opacity(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
FillRule fillRule() const { return this->model()->fillRule(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class Filter<model::Group> : public FilterBase<model::Group>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Filter(model::Group* model = nullptr) : FilterBase<model::Group>(model) {}
|
|
||||||
|
|
||||||
bool hasModel() const { return this->model() ? true : false; }
|
|
||||||
|
|
||||||
model::Transform* transform() const { return this->model() ? this->model()->mTransform : nullptr; }
|
|
||||||
VMatrix matrix(int frame) const
|
|
||||||
{
|
|
||||||
VMatrix mS, mR, mT;
|
|
||||||
if (this->hasFilter(rlottie::Property::TrScale)) {
|
|
||||||
VSize s = this->filter()->scale(rlottie::Property::TrScale, frame);
|
|
||||||
mS.scale(s.width() / 100.0, s.height() / 100.0);
|
|
||||||
}
|
|
||||||
if (this->hasFilter(rlottie::Property::TrRotation)) {
|
|
||||||
mR.rotate(this->filter()->value(rlottie::Property::TrRotation, frame));
|
|
||||||
}
|
|
||||||
if (this->hasFilter(rlottie::Property::TrPosition)) {
|
|
||||||
mT.translate(this->filter()->point(rlottie::Property::TrPosition, frame));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->model()->mTransform->matrix(frame) * mS * mR * mT;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace model
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace rlottie
|
|
||||||
|
|
||||||
#endif // LOTTIEFILTERMODEL_H
|
|
1491
vendor/github.com/Benau/go_rlottie/lottie_lottieitem.cpp
generated
vendored
1491
vendor/github.com/Benau/go_rlottie/lottie_lottieitem.cpp
generated
vendored
File diff suppressed because it is too large
Load Diff
626
vendor/github.com/Benau/go_rlottie/lottie_lottieitem.h
generated
vendored
626
vendor/github.com/Benau/go_rlottie/lottie_lottieitem.h
generated
vendored
@ -1,626 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LOTTIEITEM_H
|
|
||||||
#define LOTTIEITEM_H
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "lottie_lottiekeypath.h"
|
|
||||||
#include "lottie_lottiefiltermodel.h"
|
|
||||||
#include "rlottie.h"
|
|
||||||
#include "rlottiecommon.h"
|
|
||||||
#include "vector_varenaalloc.h"
|
|
||||||
#include "vector_vdrawable.h"
|
|
||||||
#include "vector_vmatrix.h"
|
|
||||||
#include "vector_vpainter.h"
|
|
||||||
#include "vector_vpath.h"
|
|
||||||
#include "vector_vpathmesure.h"
|
|
||||||
#include "vector_vpoint.h"
|
|
||||||
|
|
||||||
V_USE_NAMESPACE
|
|
||||||
|
|
||||||
namespace rlottie {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class VSpan {
|
|
||||||
public:
|
|
||||||
using reference = T &;
|
|
||||||
using pointer = T *;
|
|
||||||
using const_pointer = T const *;
|
|
||||||
using const_reference = T const &;
|
|
||||||
using index_type = size_t;
|
|
||||||
|
|
||||||
using iterator = pointer;
|
|
||||||
using const_iterator = const_pointer;
|
|
||||||
|
|
||||||
VSpan() = default;
|
|
||||||
VSpan(pointer data, index_type size) : _data(data), _size(size) {}
|
|
||||||
|
|
||||||
constexpr pointer data() const noexcept { return _data; }
|
|
||||||
constexpr index_type size() const noexcept { return _size; }
|
|
||||||
constexpr bool empty() const noexcept { return size() == 0; }
|
|
||||||
constexpr iterator begin() const noexcept { return data(); }
|
|
||||||
constexpr iterator end() const noexcept { return data() + size(); }
|
|
||||||
constexpr const_iterator cbegin() const noexcept { return data(); }
|
|
||||||
constexpr const_iterator cend() const noexcept { return data() + size(); }
|
|
||||||
constexpr reference operator[](index_type idx) const
|
|
||||||
{
|
|
||||||
return *(data() + idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
pointer _data{nullptr};
|
|
||||||
index_type _size{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace renderer {
|
|
||||||
|
|
||||||
using DrawableList = VSpan<VDrawable *>;
|
|
||||||
|
|
||||||
enum class DirtyFlagBit : uchar {
|
|
||||||
None = 0x00,
|
|
||||||
Matrix = 0x01,
|
|
||||||
Alpha = 0x02,
|
|
||||||
All = (Matrix | Alpha)
|
|
||||||
};
|
|
||||||
typedef vFlag<DirtyFlagBit> DirtyFlag;
|
|
||||||
|
|
||||||
class SurfaceCache {
|
|
||||||
public:
|
|
||||||
SurfaceCache() { mCache.reserve(10); }
|
|
||||||
|
|
||||||
VBitmap make_surface(
|
|
||||||
size_t width, size_t height,
|
|
||||||
VBitmap::Format format = VBitmap::Format::ARGB32_Premultiplied)
|
|
||||||
{
|
|
||||||
if (mCache.empty()) return {width, height, format};
|
|
||||||
|
|
||||||
auto surface = mCache.back();
|
|
||||||
surface.reset(width, height, format);
|
|
||||||
|
|
||||||
mCache.pop_back();
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
void release_surface(VBitmap &surface) { mCache.push_back(surface); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<VBitmap> mCache;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Drawable final : public VDrawable {
|
|
||||||
public:
|
|
||||||
void sync();
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::unique_ptr<LOTNode> mCNode{nullptr};
|
|
||||||
|
|
||||||
~Drawable() noexcept
|
|
||||||
{
|
|
||||||
if (mCNode && mCNode->mGradient.stopPtr)
|
|
||||||
free(mCNode->mGradient.stopPtr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CApiData {
|
|
||||||
CApiData();
|
|
||||||
LOTLayerNode mLayer;
|
|
||||||
std::vector<LOTMask> mMasks;
|
|
||||||
std::vector<LOTLayerNode *> mLayers;
|
|
||||||
std::vector<LOTNode *> mCNodeList;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Clipper {
|
|
||||||
public:
|
|
||||||
explicit Clipper(VSize size) : mSize(size) {}
|
|
||||||
void update(const VMatrix &matrix);
|
|
||||||
void preprocess(const VRect &clip);
|
|
||||||
VRle rle(const VRle &mask);
|
|
||||||
|
|
||||||
public:
|
|
||||||
VSize mSize;
|
|
||||||
VPath mPath;
|
|
||||||
VRle mMaskedRle;
|
|
||||||
VRasterizer mRasterizer;
|
|
||||||
bool mRasterRequest{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Mask {
|
|
||||||
public:
|
|
||||||
explicit Mask(model::Mask *data) : mData(data) {}
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag);
|
|
||||||
model::Mask::Mode maskMode() const { return mData->mMode; }
|
|
||||||
VRle rle();
|
|
||||||
void preprocess(const VRect &clip);
|
|
||||||
bool inverted() const { return mData->mInv; }
|
|
||||||
public:
|
|
||||||
model::Mask *mData{nullptr};
|
|
||||||
VPath mLocalPath;
|
|
||||||
VPath mFinalPath;
|
|
||||||
VRasterizer mRasterizer;
|
|
||||||
float mCombinedAlpha{0};
|
|
||||||
bool mRasterRequest{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handels mask property of a layer item
|
|
||||||
*/
|
|
||||||
class LayerMask {
|
|
||||||
public:
|
|
||||||
explicit LayerMask(model::Layer *layerData);
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag);
|
|
||||||
bool isStatic() const { return mStatic; }
|
|
||||||
VRle maskRle(const VRect &clipRect);
|
|
||||||
void preprocess(const VRect &clip);
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::vector<Mask> mMasks;
|
|
||||||
VRle mRle;
|
|
||||||
bool mStatic{true};
|
|
||||||
bool mDirty{true};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Layer;
|
|
||||||
|
|
||||||
class Composition {
|
|
||||||
public:
|
|
||||||
explicit Composition(std::shared_ptr<model::Composition> composition);
|
|
||||||
bool update(int frameNo, const VSize &size, bool keepAspectRatio);
|
|
||||||
VSize size() const { return mViewSize; }
|
|
||||||
void buildRenderTree();
|
|
||||||
const LOTLayerNode *renderTree() const;
|
|
||||||
bool render(const rlottie::Surface &surface);
|
|
||||||
void setValue(const std::string &keypath, LOTVariant &value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SurfaceCache mSurfaceCache;
|
|
||||||
VBitmap mSurface;
|
|
||||||
VMatrix mScaleMatrix;
|
|
||||||
VSize mViewSize;
|
|
||||||
std::shared_ptr<model::Composition> mModel;
|
|
||||||
Layer * mRootLayer{nullptr};
|
|
||||||
VArenaAlloc mAllocator{2048};
|
|
||||||
int mCurFrameNo;
|
|
||||||
bool mKeepAspectRatio{true};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Layer {
|
|
||||||
public:
|
|
||||||
virtual ~Layer() = default;
|
|
||||||
Layer &operator=(Layer &&) noexcept = delete;
|
|
||||||
Layer(model::Layer *layerData);
|
|
||||||
int id() const { return mLayerData->id(); }
|
|
||||||
int parentId() const { return mLayerData->parentId(); }
|
|
||||||
void setParentLayer(Layer *parent) { mParentLayer = parent; }
|
|
||||||
void setComplexContent(bool value) { mComplexContent = value; }
|
|
||||||
bool complexContent() const { return mComplexContent; }
|
|
||||||
virtual void update(int frameNo, const VMatrix &parentMatrix,
|
|
||||||
float parentAlpha);
|
|
||||||
VMatrix matrix(int frameNo) const;
|
|
||||||
void preprocess(const VRect &clip);
|
|
||||||
virtual DrawableList renderList() { return {}; }
|
|
||||||
virtual void render(VPainter *painter, const VRle &mask,
|
|
||||||
const VRle &matteRle, SurfaceCache &cache);
|
|
||||||
bool hasMatte()
|
|
||||||
{
|
|
||||||
if (mLayerData->mMatteType == model::MatteType::None) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
model::MatteType matteType() const { return mLayerData->mMatteType; }
|
|
||||||
bool visible() const;
|
|
||||||
virtual void buildLayerNode();
|
|
||||||
LOTLayerNode & clayer() { return mCApiData->mLayer; }
|
|
||||||
std::vector<LOTLayerNode *> &clayers() { return mCApiData->mLayers; }
|
|
||||||
std::vector<LOTMask> & cmasks() { return mCApiData->mMasks; }
|
|
||||||
std::vector<LOTNode *> & cnodes() { return mCApiData->mCNodeList; }
|
|
||||||
const char * name() const { return mLayerData->name(); }
|
|
||||||
virtual bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
|
|
||||||
LOTVariant &value);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void preprocessStage(const VRect &clip) = 0;
|
|
||||||
virtual void updateContent() = 0;
|
|
||||||
inline VMatrix combinedMatrix() const { return mCombinedMatrix; }
|
|
||||||
inline int frameNo() const { return mFrameNo; }
|
|
||||||
inline float combinedAlpha() const { return mCombinedAlpha; }
|
|
||||||
inline bool isStatic() const { return mLayerData->isStatic(); }
|
|
||||||
float opacity(int frameNo) const { return mLayerData->opacity(frameNo); }
|
|
||||||
inline DirtyFlag flag() const { return mDirtyFlag; }
|
|
||||||
bool skipRendering() const
|
|
||||||
{
|
|
||||||
return (!visible() || vIsZero(combinedAlpha()));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::unique_ptr<LayerMask> mLayerMask;
|
|
||||||
model::Layer * mLayerData{nullptr};
|
|
||||||
Layer * mParentLayer{nullptr};
|
|
||||||
VMatrix mCombinedMatrix;
|
|
||||||
float mCombinedAlpha{0.0};
|
|
||||||
int mFrameNo{-1};
|
|
||||||
DirtyFlag mDirtyFlag{DirtyFlagBit::All};
|
|
||||||
bool mComplexContent{false};
|
|
||||||
std::unique_ptr<CApiData> mCApiData;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CompLayer final : public Layer {
|
|
||||||
public:
|
|
||||||
explicit CompLayer(model::Layer *layerData, VArenaAlloc *allocator);
|
|
||||||
|
|
||||||
void render(VPainter *painter, const VRle &mask, const VRle &matteRle,
|
|
||||||
SurfaceCache &cache) final;
|
|
||||||
void buildLayerNode() final;
|
|
||||||
bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
|
|
||||||
LOTVariant &value) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void preprocessStage(const VRect &clip) final;
|
|
||||||
void updateContent() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void renderHelper(VPainter *painter, const VRle &mask, const VRle &matteRle,
|
|
||||||
SurfaceCache &cache);
|
|
||||||
void renderMatteLayer(VPainter *painter, const VRle &inheritMask,
|
|
||||||
const VRle &matteRle, Layer *layer, Layer *src,
|
|
||||||
SurfaceCache &cache);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<Layer *> mLayers;
|
|
||||||
std::unique_ptr<Clipper> mClipper;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SolidLayer final : public Layer {
|
|
||||||
public:
|
|
||||||
explicit SolidLayer(model::Layer *layerData);
|
|
||||||
void buildLayerNode() final;
|
|
||||||
DrawableList renderList() final;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void preprocessStage(const VRect &clip) final;
|
|
||||||
void updateContent() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Drawable mRenderNode;
|
|
||||||
VPath mPath;
|
|
||||||
VDrawable *mDrawableList{nullptr}; // to work with the Span api
|
|
||||||
};
|
|
||||||
|
|
||||||
class Group;
|
|
||||||
|
|
||||||
class ShapeLayer final : public Layer {
|
|
||||||
public:
|
|
||||||
explicit ShapeLayer(model::Layer *layerData, VArenaAlloc *allocator);
|
|
||||||
DrawableList renderList() final;
|
|
||||||
void buildLayerNode() final;
|
|
||||||
bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
|
|
||||||
LOTVariant &value) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void preprocessStage(const VRect &clip) final;
|
|
||||||
void updateContent() final;
|
|
||||||
std::vector<VDrawable *> mDrawableList;
|
|
||||||
Group * mRoot{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
class NullLayer final : public Layer {
|
|
||||||
public:
|
|
||||||
explicit NullLayer(model::Layer *layerData);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void preprocessStage(const VRect &) final {}
|
|
||||||
void updateContent() final;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImageLayer final : public Layer {
|
|
||||||
public:
|
|
||||||
explicit ImageLayer(model::Layer *layerData);
|
|
||||||
void buildLayerNode() final;
|
|
||||||
DrawableList renderList() final;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void preprocessStage(const VRect &clip) final;
|
|
||||||
void updateContent() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Drawable mRenderNode;
|
|
||||||
VTexture mTexture;
|
|
||||||
VPath mPath;
|
|
||||||
VDrawable *mDrawableList{nullptr}; // to work with the Span api
|
|
||||||
};
|
|
||||||
|
|
||||||
class Object {
|
|
||||||
public:
|
|
||||||
enum class Type : uchar { Unknown, Group, Shape, Paint, Trim };
|
|
||||||
virtual ~Object() = default;
|
|
||||||
Object & operator=(Object &&) noexcept = delete;
|
|
||||||
virtual void update(int frameNo, const VMatrix &parentMatrix,
|
|
||||||
float parentAlpha, const DirtyFlag &flag) = 0;
|
|
||||||
virtual void renderList(std::vector<VDrawable *> &) {}
|
|
||||||
virtual bool resolveKeyPath(LOTKeyPath &, uint, LOTVariant &)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
virtual Object::Type type() const { return Object::Type::Unknown; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Shape;
|
|
||||||
class Group : public Object {
|
|
||||||
public:
|
|
||||||
Group() = default;
|
|
||||||
explicit Group(model::Group *data, VArenaAlloc *allocator);
|
|
||||||
void addChildren(model::Group *data, VArenaAlloc *allocator);
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag) override;
|
|
||||||
void applyTrim();
|
|
||||||
void processTrimItems(std::vector<Shape *> &list);
|
|
||||||
void processPaintItems(std::vector<Shape *> &list);
|
|
||||||
void renderList(std::vector<VDrawable *> &list) override;
|
|
||||||
Object::Type type() const final { return Object::Type::Group; }
|
|
||||||
const VMatrix &matrix() const { return mMatrix; }
|
|
||||||
const char * name() const
|
|
||||||
{
|
|
||||||
static const char *TAG = "__";
|
|
||||||
return mModel.hasModel() ? mModel.name() : TAG;
|
|
||||||
}
|
|
||||||
bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
|
|
||||||
LOTVariant &value) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::vector<Object *> mContents;
|
|
||||||
VMatrix mMatrix;
|
|
||||||
|
|
||||||
private:
|
|
||||||
model::Filter<model::Group> mModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Shape : public Object {
|
|
||||||
public:
|
|
||||||
Shape(bool staticPath) : mStaticPath(staticPath) {}
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag) final;
|
|
||||||
Object::Type type() const final { return Object::Type::Shape; }
|
|
||||||
bool dirty() const { return mDirtyPath; }
|
|
||||||
const VPath &localPath() const { return mTemp; }
|
|
||||||
void finalPath(VPath &result);
|
|
||||||
void updatePath(const VPath &path)
|
|
||||||
{
|
|
||||||
mTemp = path;
|
|
||||||
mDirtyPath = true;
|
|
||||||
}
|
|
||||||
bool staticPath() const { return mStaticPath; }
|
|
||||||
void setParent(Group *parent) { mParent = parent; }
|
|
||||||
Group *parent() const { return mParent; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void updatePath(VPath &path, int frameNo) = 0;
|
|
||||||
virtual bool hasChanged(int prevFrame, int curFrame) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool hasChanged(int frameNo)
|
|
||||||
{
|
|
||||||
int prevFrame = mFrameNo;
|
|
||||||
mFrameNo = frameNo;
|
|
||||||
if (prevFrame == -1) return true;
|
|
||||||
if (mStaticPath || (prevFrame == frameNo)) return false;
|
|
||||||
return hasChanged(prevFrame, frameNo);
|
|
||||||
}
|
|
||||||
Group *mParent{nullptr};
|
|
||||||
VPath mLocalPath;
|
|
||||||
VPath mTemp;
|
|
||||||
int mFrameNo{-1};
|
|
||||||
bool mDirtyPath{true};
|
|
||||||
bool mStaticPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Rect final : public Shape {
|
|
||||||
public:
|
|
||||||
explicit Rect(model::Rect *data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void updatePath(VPath &path, int frameNo) final;
|
|
||||||
model::Rect *mData{nullptr};
|
|
||||||
|
|
||||||
bool hasChanged(int prevFrame, int curFrame) final
|
|
||||||
{
|
|
||||||
return (mData->mPos.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mSize.changed(prevFrame, curFrame) ||
|
|
||||||
mData->roundnessChanged(prevFrame, curFrame));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Ellipse final : public Shape {
|
|
||||||
public:
|
|
||||||
explicit Ellipse(model::Ellipse *data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updatePath(VPath &path, int frameNo) final;
|
|
||||||
model::Ellipse *mData{nullptr};
|
|
||||||
bool hasChanged(int prevFrame, int curFrame) final
|
|
||||||
{
|
|
||||||
return (mData->mPos.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mSize.changed(prevFrame, curFrame));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Path final : public Shape {
|
|
||||||
public:
|
|
||||||
explicit Path(model::Path *data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updatePath(VPath &path, int frameNo) final;
|
|
||||||
model::Path *mData{nullptr};
|
|
||||||
bool hasChanged(int prevFrame, int curFrame) final
|
|
||||||
{
|
|
||||||
return mData->mShape.changed(prevFrame, curFrame);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Polystar final : public Shape {
|
|
||||||
public:
|
|
||||||
explicit Polystar(model::Polystar *data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updatePath(VPath &path, int frameNo) final;
|
|
||||||
model::Polystar *mData{nullptr};
|
|
||||||
|
|
||||||
bool hasChanged(int prevFrame, int curFrame) final
|
|
||||||
{
|
|
||||||
return (mData->mPos.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mPointCount.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mInnerRadius.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mOuterRadius.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mInnerRoundness.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mOuterRoundness.changed(prevFrame, curFrame) ||
|
|
||||||
mData->mRotation.changed(prevFrame, curFrame));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Paint : public Object {
|
|
||||||
public:
|
|
||||||
Paint(bool staticContent);
|
|
||||||
void addPathItems(std::vector<Shape *> &list, size_t startOffset);
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag) override;
|
|
||||||
void renderList(std::vector<VDrawable *> &list) final;
|
|
||||||
Object::Type type() const final { return Object::Type::Paint; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool updateContent(int frameNo, const VMatrix &matrix,
|
|
||||||
float alpha) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void updateRenderNode();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::vector<Shape *> mPathItems;
|
|
||||||
Drawable mDrawable;
|
|
||||||
VPath mPath;
|
|
||||||
DirtyFlag mFlag;
|
|
||||||
bool mStaticContent;
|
|
||||||
bool mRenderNodeUpdate{true};
|
|
||||||
bool mContentToRender{true};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Fill final : public Paint {
|
|
||||||
public:
|
|
||||||
explicit Fill(model::Fill *data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
|
|
||||||
bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
|
|
||||||
LOTVariant &value) final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
model::Filter<model::Fill> mModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GradientFill final : public Paint {
|
|
||||||
public:
|
|
||||||
explicit GradientFill(model::GradientFill *data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
model::GradientFill * mData{nullptr};
|
|
||||||
std::unique_ptr<VGradient> mGradient;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Stroke : public Paint {
|
|
||||||
public:
|
|
||||||
explicit Stroke(model::Stroke *data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
|
|
||||||
bool resolveKeyPath(LOTKeyPath &keyPath, uint depth,
|
|
||||||
LOTVariant &value) final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
model::Filter<model::Stroke> mModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GradientStroke final : public Paint {
|
|
||||||
public:
|
|
||||||
explicit GradientStroke(model::GradientStroke *data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool updateContent(int frameNo, const VMatrix &matrix, float alpha) final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
model::GradientStroke * mData{nullptr};
|
|
||||||
std::unique_ptr<VGradient> mGradient;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Trim final : public Object {
|
|
||||||
public:
|
|
||||||
explicit Trim(model::Trim *data) : mData(data) {}
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag) final;
|
|
||||||
Object::Type type() const final { return Object::Type::Trim; }
|
|
||||||
void update();
|
|
||||||
void addPathItems(std::vector<Shape *> &list, size_t startOffset);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool pathDirty() const
|
|
||||||
{
|
|
||||||
for (auto &i : mPathItems) {
|
|
||||||
if (i->dirty()) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
struct Cache {
|
|
||||||
int mFrameNo{-1};
|
|
||||||
model::Trim::Segment mSegment{};
|
|
||||||
};
|
|
||||||
Cache mCache;
|
|
||||||
std::vector<Shape *> mPathItems;
|
|
||||||
model::Trim * mData{nullptr};
|
|
||||||
VPathMesure mPathMesure;
|
|
||||||
bool mDirty{true};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Repeater final : public Group {
|
|
||||||
public:
|
|
||||||
explicit Repeater(model::Repeater *data, VArenaAlloc *allocator);
|
|
||||||
void update(int frameNo, const VMatrix &parentMatrix, float parentAlpha,
|
|
||||||
const DirtyFlag &flag) final;
|
|
||||||
void renderList(std::vector<VDrawable *> &list) final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
model::Repeater *mRepeaterData{nullptr};
|
|
||||||
bool mHidden{false};
|
|
||||||
int mCopies{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace renderer
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace rlottie
|
|
||||||
|
|
||||||
#endif // LOTTIEITEM_H
|
|
339
vendor/github.com/Benau/go_rlottie/lottie_lottieitem_capi.cpp
generated
vendored
339
vendor/github.com/Benau/go_rlottie/lottie_lottieitem_capi.cpp
generated
vendored
@ -1,339 +0,0 @@
|
|||||||
/*
|
|
||||||
* Implements LottieItem functions needed
|
|
||||||
* to support renderTree() api.
|
|
||||||
* Moving all those implementation to its own
|
|
||||||
* file make clear separation as well easy of
|
|
||||||
* maintenance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lottie_lottieitem.h"
|
|
||||||
#include "vector_vdasher.h"
|
|
||||||
|
|
||||||
using namespace rlottie::internal;
|
|
||||||
|
|
||||||
renderer::CApiData::CApiData()
|
|
||||||
{
|
|
||||||
mLayer.mMaskList.ptr = nullptr;
|
|
||||||
mLayer.mMaskList.size = 0;
|
|
||||||
mLayer.mLayerList.ptr = nullptr;
|
|
||||||
mLayer.mLayerList.size = 0;
|
|
||||||
mLayer.mNodeList.ptr = nullptr;
|
|
||||||
mLayer.mNodeList.size = 0;
|
|
||||||
mLayer.mMatte = MatteNone;
|
|
||||||
mLayer.mVisible = 0;
|
|
||||||
mLayer.mAlpha = 255;
|
|
||||||
mLayer.mClipPath.ptPtr = nullptr;
|
|
||||||
mLayer.mClipPath.elmPtr = nullptr;
|
|
||||||
mLayer.mClipPath.ptCount = 0;
|
|
||||||
mLayer.mClipPath.elmCount = 0;
|
|
||||||
mLayer.keypath = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::Composition::buildRenderTree()
|
|
||||||
{
|
|
||||||
mRootLayer->buildLayerNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
const LOTLayerNode *renderer::Composition::renderTree() const
|
|
||||||
{
|
|
||||||
return &mRootLayer->clayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::CompLayer::buildLayerNode()
|
|
||||||
{
|
|
||||||
renderer::Layer::buildLayerNode();
|
|
||||||
if (mClipper) {
|
|
||||||
const auto &elm = mClipper->mPath.elements();
|
|
||||||
const auto &pts = mClipper->mPath.points();
|
|
||||||
auto ptPtr = reinterpret_cast<const float *>(pts.data());
|
|
||||||
auto elmPtr = reinterpret_cast<const char *>(elm.data());
|
|
||||||
clayer().mClipPath.ptPtr = ptPtr;
|
|
||||||
clayer().mClipPath.elmPtr = elmPtr;
|
|
||||||
clayer().mClipPath.ptCount = 2 * pts.size();
|
|
||||||
clayer().mClipPath.elmCount = elm.size();
|
|
||||||
}
|
|
||||||
if (mLayers.size() != clayers().size()) {
|
|
||||||
for (const auto &layer : mLayers) {
|
|
||||||
layer->buildLayerNode();
|
|
||||||
clayers().push_back(&layer->clayer());
|
|
||||||
}
|
|
||||||
clayer().mLayerList.ptr = clayers().data();
|
|
||||||
clayer().mLayerList.size = clayers().size();
|
|
||||||
} else {
|
|
||||||
for (const auto &layer : mLayers) {
|
|
||||||
layer->buildLayerNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::ShapeLayer::buildLayerNode()
|
|
||||||
{
|
|
||||||
renderer::Layer::buildLayerNode();
|
|
||||||
|
|
||||||
auto renderlist = renderList();
|
|
||||||
|
|
||||||
cnodes().clear();
|
|
||||||
for (auto &i : renderlist) {
|
|
||||||
auto lotDrawable = static_cast<renderer::Drawable *>(i);
|
|
||||||
lotDrawable->sync();
|
|
||||||
cnodes().push_back(lotDrawable->mCNode.get());
|
|
||||||
}
|
|
||||||
clayer().mNodeList.ptr = cnodes().data();
|
|
||||||
clayer().mNodeList.size = cnodes().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::Layer::buildLayerNode()
|
|
||||||
{
|
|
||||||
if (!mCApiData) {
|
|
||||||
mCApiData = std::make_unique<renderer::CApiData>();
|
|
||||||
clayer().keypath = name();
|
|
||||||
}
|
|
||||||
if (complexContent()) clayer().mAlpha = uchar(combinedAlpha() * 255.f);
|
|
||||||
clayer().mVisible = visible();
|
|
||||||
// update matte
|
|
||||||
if (hasMatte()) {
|
|
||||||
switch (mLayerData->mMatteType) {
|
|
||||||
case model::MatteType::Alpha:
|
|
||||||
clayer().mMatte = MatteAlpha;
|
|
||||||
break;
|
|
||||||
case model::MatteType::AlphaInv:
|
|
||||||
clayer().mMatte = MatteAlphaInv;
|
|
||||||
break;
|
|
||||||
case model::MatteType::Luma:
|
|
||||||
clayer().mMatte = MatteLuma;
|
|
||||||
break;
|
|
||||||
case model::MatteType::LumaInv:
|
|
||||||
clayer().mMatte = MatteLumaInv;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
clayer().mMatte = MatteNone;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mLayerMask) {
|
|
||||||
cmasks().clear();
|
|
||||||
cmasks().resize(mLayerMask->mMasks.size());
|
|
||||||
size_t i = 0;
|
|
||||||
for (const auto &mask : mLayerMask->mMasks) {
|
|
||||||
auto & cNode = cmasks()[i++];
|
|
||||||
const auto &elm = mask.mFinalPath.elements();
|
|
||||||
const auto &pts = mask.mFinalPath.points();
|
|
||||||
auto ptPtr = reinterpret_cast<const float *>(pts.data());
|
|
||||||
auto elmPtr = reinterpret_cast<const char *>(elm.data());
|
|
||||||
cNode.mPath.ptPtr = ptPtr;
|
|
||||||
cNode.mPath.ptCount = 2 * pts.size();
|
|
||||||
cNode.mPath.elmPtr = elmPtr;
|
|
||||||
cNode.mPath.elmCount = elm.size();
|
|
||||||
cNode.mAlpha = uchar(mask.mCombinedAlpha * 255.0f);
|
|
||||||
switch (mask.maskMode()) {
|
|
||||||
case model::Mask::Mode::Add:
|
|
||||||
cNode.mMode = MaskAdd;
|
|
||||||
break;
|
|
||||||
case model::Mask::Mode::Substarct:
|
|
||||||
cNode.mMode = MaskSubstract;
|
|
||||||
break;
|
|
||||||
case model::Mask::Mode::Intersect:
|
|
||||||
cNode.mMode = MaskIntersect;
|
|
||||||
break;
|
|
||||||
case model::Mask::Mode::Difference:
|
|
||||||
cNode.mMode = MaskDifference;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cNode.mMode = MaskAdd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clayer().mMaskList.ptr = cmasks().data();
|
|
||||||
clayer().mMaskList.size = cmasks().size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::SolidLayer::buildLayerNode()
|
|
||||||
{
|
|
||||||
renderer::Layer::buildLayerNode();
|
|
||||||
|
|
||||||
auto renderlist = renderList();
|
|
||||||
|
|
||||||
cnodes().clear();
|
|
||||||
for (auto &i : renderlist) {
|
|
||||||
auto lotDrawable = static_cast<renderer::Drawable *>(i);
|
|
||||||
lotDrawable->sync();
|
|
||||||
cnodes().push_back(lotDrawable->mCNode.get());
|
|
||||||
}
|
|
||||||
clayer().mNodeList.ptr = cnodes().data();
|
|
||||||
clayer().mNodeList.size = cnodes().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::ImageLayer::buildLayerNode()
|
|
||||||
{
|
|
||||||
renderer::Layer::buildLayerNode();
|
|
||||||
|
|
||||||
auto renderlist = renderList();
|
|
||||||
|
|
||||||
cnodes().clear();
|
|
||||||
for (auto &i : renderlist) {
|
|
||||||
auto lotDrawable = static_cast<renderer::Drawable *>(i);
|
|
||||||
lotDrawable->sync();
|
|
||||||
|
|
||||||
lotDrawable->mCNode->mImageInfo.data =
|
|
||||||
lotDrawable->mBrush.mTexture->mBitmap.data();
|
|
||||||
lotDrawable->mCNode->mImageInfo.width =
|
|
||||||
int(lotDrawable->mBrush.mTexture->mBitmap.width());
|
|
||||||
lotDrawable->mCNode->mImageInfo.height =
|
|
||||||
int(lotDrawable->mBrush.mTexture->mBitmap.height());
|
|
||||||
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m11 = combinedMatrix().m_11();
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m12 = combinedMatrix().m_12();
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m13 = combinedMatrix().m_13();
|
|
||||||
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m21 = combinedMatrix().m_21();
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m22 = combinedMatrix().m_22();
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m23 = combinedMatrix().m_23();
|
|
||||||
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m31 = combinedMatrix().m_tx();
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m32 = combinedMatrix().m_ty();
|
|
||||||
lotDrawable->mCNode->mImageInfo.mMatrix.m33 = combinedMatrix().m_33();
|
|
||||||
|
|
||||||
// Alpha calculation already combined.
|
|
||||||
lotDrawable->mCNode->mImageInfo.mAlpha =
|
|
||||||
uchar(lotDrawable->mBrush.mTexture->mAlpha);
|
|
||||||
|
|
||||||
cnodes().push_back(lotDrawable->mCNode.get());
|
|
||||||
}
|
|
||||||
clayer().mNodeList.ptr = cnodes().data();
|
|
||||||
clayer().mNodeList.size = cnodes().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateGStops(LOTNode *n, const VGradient *grad)
|
|
||||||
{
|
|
||||||
if (grad->mStops.size() != n->mGradient.stopCount) {
|
|
||||||
if (n->mGradient.stopCount) free(n->mGradient.stopPtr);
|
|
||||||
n->mGradient.stopCount = grad->mStops.size();
|
|
||||||
n->mGradient.stopPtr = (LOTGradientStop *)malloc(
|
|
||||||
n->mGradient.stopCount * sizeof(LOTGradientStop));
|
|
||||||
}
|
|
||||||
|
|
||||||
LOTGradientStop *ptr = n->mGradient.stopPtr;
|
|
||||||
for (const auto &i : grad->mStops) {
|
|
||||||
ptr->pos = i.first;
|
|
||||||
ptr->a = uchar(i.second.alpha() * grad->alpha());
|
|
||||||
ptr->r = i.second.red();
|
|
||||||
ptr->g = i.second.green();
|
|
||||||
ptr->b = i.second.blue();
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderer::Drawable::sync()
|
|
||||||
{
|
|
||||||
if (!mCNode) {
|
|
||||||
mCNode = std::make_unique<LOTNode>();
|
|
||||||
mCNode->mGradient.stopPtr = nullptr;
|
|
||||||
mCNode->mGradient.stopCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCNode->mFlag = ChangeFlagNone;
|
|
||||||
if (mFlag & DirtyState::None) return;
|
|
||||||
|
|
||||||
if (mFlag & DirtyState::Path) {
|
|
||||||
applyDashOp();
|
|
||||||
const std::vector<VPath::Element> &elm = mPath.elements();
|
|
||||||
const std::vector<VPointF> & pts = mPath.points();
|
|
||||||
const float *ptPtr = reinterpret_cast<const float *>(pts.data());
|
|
||||||
const char * elmPtr = reinterpret_cast<const char *>(elm.data());
|
|
||||||
mCNode->mPath.elmPtr = elmPtr;
|
|
||||||
mCNode->mPath.elmCount = elm.size();
|
|
||||||
mCNode->mPath.ptPtr = ptPtr;
|
|
||||||
mCNode->mPath.ptCount = 2 * pts.size();
|
|
||||||
mCNode->mFlag |= ChangeFlagPath;
|
|
||||||
mCNode->keypath = name();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mStrokeInfo) {
|
|
||||||
mCNode->mStroke.width = mStrokeInfo->width;
|
|
||||||
mCNode->mStroke.miterLimit = mStrokeInfo->miterLimit;
|
|
||||||
mCNode->mStroke.enable = 1;
|
|
||||||
|
|
||||||
switch (mStrokeInfo->cap) {
|
|
||||||
case CapStyle::Flat:
|
|
||||||
mCNode->mStroke.cap = LOTCapStyle::CapFlat;
|
|
||||||
break;
|
|
||||||
case CapStyle::Square:
|
|
||||||
mCNode->mStroke.cap = LOTCapStyle::CapSquare;
|
|
||||||
break;
|
|
||||||
case CapStyle::Round:
|
|
||||||
mCNode->mStroke.cap = LOTCapStyle::CapRound;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mStrokeInfo->join) {
|
|
||||||
case JoinStyle::Miter:
|
|
||||||
mCNode->mStroke.join = LOTJoinStyle::JoinMiter;
|
|
||||||
break;
|
|
||||||
case JoinStyle::Bevel:
|
|
||||||
mCNode->mStroke.join = LOTJoinStyle::JoinBevel;
|
|
||||||
break;
|
|
||||||
case JoinStyle::Round:
|
|
||||||
mCNode->mStroke.join = LOTJoinStyle::JoinRound;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mCNode->mStroke.join = LOTJoinStyle::JoinMiter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mCNode->mStroke.enable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mFillRule) {
|
|
||||||
case FillRule::EvenOdd:
|
|
||||||
mCNode->mFillRule = LOTFillRule::FillEvenOdd;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mCNode->mFillRule = LOTFillRule::FillWinding;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mBrush.type()) {
|
|
||||||
case VBrush::Type::Solid:
|
|
||||||
mCNode->mBrushType = LOTBrushType::BrushSolid;
|
|
||||||
mCNode->mColor.r = mBrush.mColor.r;
|
|
||||||
mCNode->mColor.g = mBrush.mColor.g;
|
|
||||||
mCNode->mColor.b = mBrush.mColor.b;
|
|
||||||
mCNode->mColor.a = mBrush.mColor.a;
|
|
||||||
break;
|
|
||||||
case VBrush::Type::LinearGradient: {
|
|
||||||
mCNode->mBrushType = LOTBrushType::BrushGradient;
|
|
||||||
mCNode->mGradient.type = LOTGradientType::GradientLinear;
|
|
||||||
VPointF s = mBrush.mGradient->mMatrix.map(
|
|
||||||
{mBrush.mGradient->linear.x1, mBrush.mGradient->linear.y1});
|
|
||||||
VPointF e = mBrush.mGradient->mMatrix.map(
|
|
||||||
{mBrush.mGradient->linear.x2, mBrush.mGradient->linear.y2});
|
|
||||||
mCNode->mGradient.start.x = s.x();
|
|
||||||
mCNode->mGradient.start.y = s.y();
|
|
||||||
mCNode->mGradient.end.x = e.x();
|
|
||||||
mCNode->mGradient.end.y = e.y();
|
|
||||||
updateGStops(mCNode.get(), mBrush.mGradient);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VBrush::Type::RadialGradient: {
|
|
||||||
mCNode->mBrushType = LOTBrushType::BrushGradient;
|
|
||||||
mCNode->mGradient.type = LOTGradientType::GradientRadial;
|
|
||||||
VPointF c = mBrush.mGradient->mMatrix.map(
|
|
||||||
{mBrush.mGradient->radial.cx, mBrush.mGradient->radial.cy});
|
|
||||||
VPointF f = mBrush.mGradient->mMatrix.map(
|
|
||||||
{mBrush.mGradient->radial.fx, mBrush.mGradient->radial.fy});
|
|
||||||
mCNode->mGradient.center.x = c.x();
|
|
||||||
mCNode->mGradient.center.y = c.y();
|
|
||||||
mCNode->mGradient.focal.x = f.x();
|
|
||||||
mCNode->mGradient.focal.y = f.y();
|
|
||||||
|
|
||||||
float scale = mBrush.mGradient->mMatrix.scale();
|
|
||||||
mCNode->mGradient.cradius = mBrush.mGradient->radial.cradius * scale;
|
|
||||||
mCNode->mGradient.fradius = mBrush.mGradient->radial.fradius * scale;
|
|
||||||
updateGStops(mCNode.get(), mBrush.mGradient);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
86
vendor/github.com/Benau/go_rlottie/lottie_lottiekeypath.cpp
generated
vendored
86
vendor/github.com/Benau/go_rlottie/lottie_lottiekeypath.cpp
generated
vendored
@ -1,86 +0,0 @@
|
|||||||
#include "lottie_lottiekeypath.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
LOTKeyPath::LOTKeyPath(const std::string &keyPath)
|
|
||||||
{
|
|
||||||
std::stringstream ss(keyPath);
|
|
||||||
std::string item;
|
|
||||||
|
|
||||||
while (getline(ss, item, '.')) {
|
|
||||||
mKeys.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LOTKeyPath::matches(const std::string &key, uint depth)
|
|
||||||
{
|
|
||||||
if (skip(key)) {
|
|
||||||
// This is an object we programatically create.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (depth > size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ((mKeys[depth] == key) || (mKeys[depth] == "*") ||
|
|
||||||
(mKeys[depth] == "**")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint LOTKeyPath::nextDepth(const std::string key, uint depth)
|
|
||||||
{
|
|
||||||
if (skip(key)) {
|
|
||||||
// If it's a container then we added programatically and it isn't a part
|
|
||||||
// of the keypath.
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
if (mKeys[depth] != "**") {
|
|
||||||
// If it's not a globstar then it is part of the keypath.
|
|
||||||
return depth + 1;
|
|
||||||
}
|
|
||||||
if (depth == size()) {
|
|
||||||
// The last key is a globstar.
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
if (mKeys[depth + 1] == key) {
|
|
||||||
// We are a globstar and the next key is our current key so consume
|
|
||||||
// both.
|
|
||||||
return depth + 2;
|
|
||||||
}
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LOTKeyPath::fullyResolvesTo(const std::string key, uint depth)
|
|
||||||
{
|
|
||||||
if (depth > mKeys.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLastDepth = (depth == size());
|
|
||||||
|
|
||||||
if (!isGlobstar(depth)) {
|
|
||||||
bool matches = (mKeys[depth] == key) || isGlob(depth);
|
|
||||||
return (isLastDepth || (depth == size() - 1 && endsWithGlobstar())) &&
|
|
||||||
matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isGlobstarButNextKeyMatches = !isLastDepth && mKeys[depth + 1] == key;
|
|
||||||
if (isGlobstarButNextKeyMatches) {
|
|
||||||
return depth == size() - 1 ||
|
|
||||||
(depth == size() - 2 && endsWithGlobstar());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLastDepth) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (depth + 1 < size()) {
|
|
||||||
// We are a globstar but there is more than 1 key after the globstar we
|
|
||||||
// we can't fully match.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Return whether the next key (which we now know is the last one) is the
|
|
||||||
// same as the current key.
|
|
||||||
return mKeys[depth + 1] == key;
|
|
||||||
}
|
|
53
vendor/github.com/Benau/go_rlottie/lottie_lottiekeypath.h
generated
vendored
53
vendor/github.com/Benau/go_rlottie/lottie_lottiekeypath.h
generated
vendored
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LOTTIEKEYPATH_H
|
|
||||||
#define LOTTIEKEYPATH_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include "vector_vglobal.h"
|
|
||||||
|
|
||||||
class LOTKeyPath {
|
|
||||||
public:
|
|
||||||
LOTKeyPath(const std::string &keyPath);
|
|
||||||
bool matches(const std::string &key, uint depth);
|
|
||||||
uint nextDepth(const std::string key, uint depth);
|
|
||||||
bool fullyResolvesTo(const std::string key, uint depth);
|
|
||||||
|
|
||||||
bool propagate(const std::string key, uint depth)
|
|
||||||
{
|
|
||||||
return skip(key) ? true : (depth < size()) || (mKeys[depth] == "**");
|
|
||||||
}
|
|
||||||
bool skip(const std::string &key) const { return key == "__"; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isGlobstar(uint depth) const { return mKeys[depth] == "**"; }
|
|
||||||
bool isGlob(uint depth) const { return mKeys[depth] == "*"; }
|
|
||||||
bool endsWithGlobstar() const { return mKeys.back() == "**"; }
|
|
||||||
size_t size() const { return mKeys.size() - 1; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::string> mKeys;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LOTTIEKEYPATH_H
|
|
169
vendor/github.com/Benau/go_rlottie/lottie_lottieloader.cpp
generated
vendored
169
vendor/github.com/Benau/go_rlottie/lottie_lottieloader.cpp
generated
vendored
@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "lottie_lottiemodel.h"
|
|
||||||
|
|
||||||
using namespace rlottie::internal;
|
|
||||||
|
|
||||||
#ifdef LOTTIE_CACHE_SUPPORT
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
class ModelCache {
|
|
||||||
public:
|
|
||||||
static ModelCache &instance()
|
|
||||||
{
|
|
||||||
static ModelCache singleton;
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
std::shared_ptr<model::Composition> find(const std::string &key)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(mMutex);
|
|
||||||
|
|
||||||
if (!mcacheSize) return nullptr;
|
|
||||||
|
|
||||||
auto search = mHash.find(key);
|
|
||||||
|
|
||||||
return (search != mHash.end()) ? search->second : nullptr;
|
|
||||||
}
|
|
||||||
void add(const std::string &key, std::shared_ptr<model::Composition> value)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(mMutex);
|
|
||||||
|
|
||||||
if (!mcacheSize) return;
|
|
||||||
|
|
||||||
//@TODO just remove the 1st element
|
|
||||||
// not the best of LRU logic
|
|
||||||
if (mcacheSize == mHash.size()) mHash.erase(mHash.cbegin());
|
|
||||||
|
|
||||||
mHash[key] = std::move(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void configureCacheSize(size_t cacheSize)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(mMutex);
|
|
||||||
mcacheSize = cacheSize;
|
|
||||||
|
|
||||||
if (!mcacheSize) mHash.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ModelCache() = default;
|
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<model::Composition>> mHash;
|
|
||||||
std::mutex mMutex;
|
|
||||||
size_t mcacheSize{10};
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
class ModelCache {
|
|
||||||
public:
|
|
||||||
static ModelCache &instance()
|
|
||||||
{
|
|
||||||
static ModelCache singleton;
|
|
||||||
return singleton;
|
|
||||||
}
|
|
||||||
std::shared_ptr<model::Composition> find(const std::string &)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
void add(const std::string &, std::shared_ptr<model::Composition>) {}
|
|
||||||
void configureCacheSize(size_t) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static std::string dirname(const std::string &path)
|
|
||||||
{
|
|
||||||
const char *ptr = strrchr(path.c_str(), '/');
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (ptr) ptr = strrchr(ptr + 1, '\\');
|
|
||||||
#endif
|
|
||||||
int len = int(ptr + 1 - path.c_str()); // +1 to include '/'
|
|
||||||
return std::string(path, 0, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void model::configureModelCacheSize(size_t cacheSize)
|
|
||||||
{
|
|
||||||
ModelCache::instance().configureCacheSize(cacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<model::Composition> model::loadFromFile(const std::string &path,
|
|
||||||
bool cachePolicy)
|
|
||||||
{
|
|
||||||
if (cachePolicy) {
|
|
||||||
auto obj = ModelCache::instance().find(path);
|
|
||||||
if (obj) return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream f;
|
|
||||||
f.open(path);
|
|
||||||
|
|
||||||
if (!f.is_open()) {
|
|
||||||
vCritical << "failed to open file = " << path.c_str();
|
|
||||||
return {};
|
|
||||||
} else {
|
|
||||||
std::string content;
|
|
||||||
|
|
||||||
std::getline(f, content, '\0');
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
if (content.empty()) return {};
|
|
||||||
|
|
||||||
auto obj = internal::model::parse(const_cast<char *>(content.c_str()),
|
|
||||||
dirname(path));
|
|
||||||
|
|
||||||
if (obj && cachePolicy) ModelCache::instance().add(path, obj);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<model::Composition> model::loadFromData(
|
|
||||||
std::string jsonData, const std::string &key, std::string resourcePath,
|
|
||||||
bool cachePolicy)
|
|
||||||
{
|
|
||||||
if (cachePolicy) {
|
|
||||||
auto obj = ModelCache::instance().find(key);
|
|
||||||
if (obj) return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto obj = internal::model::parse(const_cast<char *>(jsonData.c_str()),
|
|
||||||
std::move(resourcePath));
|
|
||||||
|
|
||||||
if (obj && cachePolicy) ModelCache::instance().add(key, obj);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<model::Composition> model::loadFromData(
|
|
||||||
std::string jsonData, std::string resourcePath, model::ColorFilter filter)
|
|
||||||
{
|
|
||||||
return internal::model::parse(const_cast<char *>(jsonData.c_str()),
|
|
||||||
std::move(resourcePath), std::move(filter));
|
|
||||||
}
|
|
390
vendor/github.com/Benau/go_rlottie/lottie_lottiemodel.cpp
generated
vendored
390
vendor/github.com/Benau/go_rlottie/lottie_lottiemodel.cpp
generated
vendored
@ -1,390 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lottie_lottiemodel.h"
|
|
||||||
#include <cassert>
|
|
||||||
#include <iterator>
|
|
||||||
#include <stack>
|
|
||||||
#include "vector_vimageloader.h"
|
|
||||||
#include "vector_vline.h"
|
|
||||||
|
|
||||||
using namespace rlottie::internal;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We process the iterator objects in the children list
|
|
||||||
* by iterating from back to front. when we find a repeater object
|
|
||||||
* we remove the objects from satrt till repeater object and then place
|
|
||||||
* under a new shape group object which we add it as children to the repeater
|
|
||||||
* object.
|
|
||||||
* Then we visit the childrens of the newly created shape group object to
|
|
||||||
* process the remaining repeater object(when children list contains more than
|
|
||||||
* one repeater).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class LottieRepeaterProcesser {
|
|
||||||
public:
|
|
||||||
void visitChildren(model::Group *obj)
|
|
||||||
{
|
|
||||||
for (auto i = obj->mChildren.rbegin(); i != obj->mChildren.rend();
|
|
||||||
++i) {
|
|
||||||
auto child = (*i);
|
|
||||||
if (child->type() == model::Object::Type::Repeater) {
|
|
||||||
model::Repeater *repeater =
|
|
||||||
static_cast<model::Repeater *>(child);
|
|
||||||
// check if this repeater is already processed
|
|
||||||
// can happen if the layer is an asset and referenced by
|
|
||||||
// multiple layer.
|
|
||||||
if (repeater->processed()) continue;
|
|
||||||
|
|
||||||
repeater->markProcessed();
|
|
||||||
|
|
||||||
auto content = repeater->content();
|
|
||||||
// 1. increment the reverse iterator to point to the
|
|
||||||
// object before the repeater
|
|
||||||
++i;
|
|
||||||
// 2. move all the children till repater to the group
|
|
||||||
std::move(obj->mChildren.begin(), i.base(),
|
|
||||||
back_inserter(content->mChildren));
|
|
||||||
// 3. erase the objects from the original children list
|
|
||||||
obj->mChildren.erase(obj->mChildren.begin(), i.base());
|
|
||||||
|
|
||||||
// 5. visit newly created group to process remaining repeater
|
|
||||||
// object.
|
|
||||||
visitChildren(content);
|
|
||||||
// 6. exit the loop as the current iterators are invalid
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
visit(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void visit(model::Object *obj)
|
|
||||||
{
|
|
||||||
switch (obj->type()) {
|
|
||||||
case model::Object::Type::Group:
|
|
||||||
case model::Object::Type::Layer: {
|
|
||||||
visitChildren(static_cast<model::Group *>(obj));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class LottieUpdateStatVisitor {
|
|
||||||
model::Composition::Stats *stat;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit LottieUpdateStatVisitor(model::Composition::Stats *s) : stat(s) {}
|
|
||||||
void visitChildren(model::Group *obj)
|
|
||||||
{
|
|
||||||
for (const auto &child : obj->mChildren) {
|
|
||||||
if (child) visit(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void visitLayer(model::Layer *layer)
|
|
||||||
{
|
|
||||||
switch (layer->mLayerType) {
|
|
||||||
case model::Layer::Type::Precomp:
|
|
||||||
stat->precompLayerCount++;
|
|
||||||
break;
|
|
||||||
case model::Layer::Type::Null:
|
|
||||||
stat->nullLayerCount++;
|
|
||||||
break;
|
|
||||||
case model::Layer::Type::Shape:
|
|
||||||
stat->shapeLayerCount++;
|
|
||||||
break;
|
|
||||||
case model::Layer::Type::Solid:
|
|
||||||
stat->solidLayerCount++;
|
|
||||||
break;
|
|
||||||
case model::Layer::Type::Image:
|
|
||||||
stat->imageLayerCount++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
visitChildren(layer);
|
|
||||||
}
|
|
||||||
void visit(model::Object *obj)
|
|
||||||
{
|
|
||||||
switch (obj->type()) {
|
|
||||||
case model::Object::Type::Layer: {
|
|
||||||
visitLayer(static_cast<model::Layer *>(obj));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case model::Object::Type::Repeater: {
|
|
||||||
visitChildren(static_cast<model::Repeater *>(obj)->content());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case model::Object::Type::Group: {
|
|
||||||
visitChildren(static_cast<model::Group *>(obj));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void model::Composition::processRepeaterObjects()
|
|
||||||
{
|
|
||||||
LottieRepeaterProcesser visitor;
|
|
||||||
visitor.visit(mRootLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void model::Composition::updateStats()
|
|
||||||
{
|
|
||||||
LottieUpdateStatVisitor visitor(&mStats);
|
|
||||||
visitor.visit(mRootLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
VMatrix model::Repeater::Transform::matrix(int frameNo, float multiplier) const
|
|
||||||
{
|
|
||||||
VPointF scale = mScale.value(frameNo) / 100.f;
|
|
||||||
scale.setX(std::pow(scale.x(), multiplier));
|
|
||||||
scale.setY(std::pow(scale.y(), multiplier));
|
|
||||||
VMatrix m;
|
|
||||||
m.translate(mPosition.value(frameNo) * multiplier)
|
|
||||||
.translate(mAnchor.value(frameNo))
|
|
||||||
.scale(scale)
|
|
||||||
.rotate(mRotation.value(frameNo) * multiplier)
|
|
||||||
.translate(-mAnchor.value(frameNo));
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
VMatrix model::Transform::Data::matrix(int frameNo, bool autoOrient) const
|
|
||||||
{
|
|
||||||
VMatrix m;
|
|
||||||
VPointF position;
|
|
||||||
if (mExtra && mExtra->mSeparate) {
|
|
||||||
position.setX(mExtra->mSeparateX.value(frameNo));
|
|
||||||
position.setY(mExtra->mSeparateY.value(frameNo));
|
|
||||||
} else {
|
|
||||||
position = mPosition.value(frameNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
float angle = autoOrient ? mPosition.angle(frameNo) : 0;
|
|
||||||
if (mExtra && mExtra->m3DData) {
|
|
||||||
m.translate(position)
|
|
||||||
.rotate(mExtra->m3DRz.value(frameNo) + angle)
|
|
||||||
.rotate(mExtra->m3DRy.value(frameNo), VMatrix::Axis::Y)
|
|
||||||
.rotate(mExtra->m3DRx.value(frameNo), VMatrix::Axis::X)
|
|
||||||
.scale(mScale.value(frameNo) / 100.f)
|
|
||||||
.translate(-mAnchor.value(frameNo));
|
|
||||||
} else {
|
|
||||||
m.translate(position)
|
|
||||||
.rotate(mRotation.value(frameNo) + angle)
|
|
||||||
.scale(mScale.value(frameNo) / 100.f)
|
|
||||||
.translate(-mAnchor.value(frameNo));
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
void model::Dash::getDashInfo(int frameNo, std::vector<float> &result) const
|
|
||||||
{
|
|
||||||
result.clear();
|
|
||||||
|
|
||||||
if (mData.size() <= 1) return;
|
|
||||||
|
|
||||||
if (result.capacity() < mData.size()) result.reserve(mData.size() + 1);
|
|
||||||
|
|
||||||
for (const auto &elm : mData) result.push_back(elm.value(frameNo));
|
|
||||||
|
|
||||||
// if the size is even then we are missing last
|
|
||||||
// gap information which is same as the last dash value
|
|
||||||
// copy it from the last dash value.
|
|
||||||
// NOTE: last value is the offset and last-1 is the last dash value.
|
|
||||||
auto size = result.size();
|
|
||||||
if ((size % 2) == 0) {
|
|
||||||
// copy offset value to end.
|
|
||||||
result.push_back(result.back());
|
|
||||||
// copy dash value to gap.
|
|
||||||
result[size - 1] = result[size - 2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Both the color stops and opacity stops are in the same array.
|
|
||||||
* There are {@link #colorPoints} colors sequentially as:
|
|
||||||
* [
|
|
||||||
* ...,
|
|
||||||
* position,
|
|
||||||
* red,
|
|
||||||
* green,
|
|
||||||
* blue,
|
|
||||||
* ...
|
|
||||||
* ]
|
|
||||||
*
|
|
||||||
* The remainder of the array is the opacity stops sequentially as:
|
|
||||||
* [
|
|
||||||
* ...,
|
|
||||||
* position,
|
|
||||||
* opacity,
|
|
||||||
* ...
|
|
||||||
* ]
|
|
||||||
*/
|
|
||||||
void model::Gradient::populate(VGradientStops &stops, int frameNo)
|
|
||||||
{
|
|
||||||
model::Gradient::Data gradData = mGradient.value(frameNo);
|
|
||||||
auto size = gradData.mGradient.size();
|
|
||||||
float * ptr = gradData.mGradient.data();
|
|
||||||
int colorPoints = mColorPoints;
|
|
||||||
if (colorPoints == -1) { // for legacy bodymovin (ref: lottie-android)
|
|
||||||
colorPoints = int(size / 4);
|
|
||||||
}
|
|
||||||
auto opacityArraySize = size - colorPoints * 4;
|
|
||||||
float *opacityPtr = ptr + (colorPoints * 4);
|
|
||||||
stops.clear();
|
|
||||||
size_t j = 0;
|
|
||||||
for (int i = 0; i < colorPoints; i++) {
|
|
||||||
float colorStop = ptr[0];
|
|
||||||
model::Color color = model::Color(ptr[1], ptr[2], ptr[3]);
|
|
||||||
if (opacityArraySize) {
|
|
||||||
if (j == opacityArraySize) {
|
|
||||||
// already reached the end
|
|
||||||
float stop1 = opacityPtr[j - 4];
|
|
||||||
float op1 = opacityPtr[j - 3];
|
|
||||||
float stop2 = opacityPtr[j - 2];
|
|
||||||
float op2 = opacityPtr[j - 1];
|
|
||||||
if (colorStop > stop2) {
|
|
||||||
stops.push_back(
|
|
||||||
std::make_pair(colorStop, color.toColor(op2)));
|
|
||||||
} else {
|
|
||||||
float progress = (colorStop - stop1) / (stop2 - stop1);
|
|
||||||
float opacity = op1 + progress * (op2 - op1);
|
|
||||||
stops.push_back(
|
|
||||||
std::make_pair(colorStop, color.toColor(opacity)));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (; j < opacityArraySize; j += 2) {
|
|
||||||
float opacityStop = opacityPtr[j];
|
|
||||||
if (opacityStop < colorStop) {
|
|
||||||
// add a color using opacity stop
|
|
||||||
stops.push_back(std::make_pair(
|
|
||||||
opacityStop, color.toColor(opacityPtr[j + 1])));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// add a color using color stop
|
|
||||||
if (j == 0) {
|
|
||||||
stops.push_back(std::make_pair(
|
|
||||||
colorStop, color.toColor(opacityPtr[j + 1])));
|
|
||||||
} else {
|
|
||||||
float progress = (colorStop - opacityPtr[j - 2]) /
|
|
||||||
(opacityPtr[j] - opacityPtr[j - 2]);
|
|
||||||
float opacity =
|
|
||||||
opacityPtr[j - 1] +
|
|
||||||
progress * (opacityPtr[j + 1] - opacityPtr[j - 1]);
|
|
||||||
stops.push_back(
|
|
||||||
std::make_pair(colorStop, color.toColor(opacity)));
|
|
||||||
}
|
|
||||||
j += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stops.push_back(std::make_pair(colorStop, color.toColor()));
|
|
||||||
}
|
|
||||||
ptr += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void model::Gradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
|
|
||||||
{
|
|
||||||
bool init = false;
|
|
||||||
if (!grad) {
|
|
||||||
if (mGradientType == 1)
|
|
||||||
grad = std::make_unique<VGradient>(VGradient::Type::Linear);
|
|
||||||
else
|
|
||||||
grad = std::make_unique<VGradient>(VGradient::Type::Radial);
|
|
||||||
grad->mSpread = VGradient::Spread::Pad;
|
|
||||||
init = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mGradient.isStatic() || init) {
|
|
||||||
populate(grad->mStops, frameNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mGradientType == 1) { // linear gradient
|
|
||||||
VPointF start = mStartPoint.value(frameNo);
|
|
||||||
VPointF end = mEndPoint.value(frameNo);
|
|
||||||
grad->linear.x1 = start.x();
|
|
||||||
grad->linear.y1 = start.y();
|
|
||||||
grad->linear.x2 = end.x();
|
|
||||||
grad->linear.y2 = end.y();
|
|
||||||
} else { // radial gradient
|
|
||||||
VPointF start = mStartPoint.value(frameNo);
|
|
||||||
VPointF end = mEndPoint.value(frameNo);
|
|
||||||
grad->radial.cx = start.x();
|
|
||||||
grad->radial.cy = start.y();
|
|
||||||
grad->radial.cradius =
|
|
||||||
VLine::length(start.x(), start.y(), end.x(), end.y());
|
|
||||||
/*
|
|
||||||
* Focal point is the point lives in highlight length distance from
|
|
||||||
* center along the line (start, end) and rotated by highlight angle.
|
|
||||||
* below calculation first finds the quadrant(angle) on which the point
|
|
||||||
* lives by applying inverse slope formula then adds the rotation angle
|
|
||||||
* to find the final angle. then point is retrived using circle equation
|
|
||||||
* of center, angle and distance.
|
|
||||||
*/
|
|
||||||
float progress = mHighlightLength.value(frameNo) / 100.0f;
|
|
||||||
if (vCompare(progress, 1.0f)) progress = 0.99f;
|
|
||||||
float startAngle = VLine(start, end).angle();
|
|
||||||
float highlightAngle = mHighlightAngle.value(frameNo);
|
|
||||||
static constexpr float K_PI = 3.1415926f;
|
|
||||||
float angle = (startAngle + highlightAngle) * (K_PI / 180.0f);
|
|
||||||
grad->radial.fx =
|
|
||||||
grad->radial.cx + std::cos(angle) * progress * grad->radial.cradius;
|
|
||||||
grad->radial.fy =
|
|
||||||
grad->radial.cy + std::sin(angle) * progress * grad->radial.cradius;
|
|
||||||
// Lottie dosen't have any focal radius concept.
|
|
||||||
grad->radial.fradius = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void model::Asset::loadImageData(std::string data)
|
|
||||||
{
|
|
||||||
if (!data.empty())
|
|
||||||
mBitmap = VImageLoader::instance().load(data.c_str(), data.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
void model::Asset::loadImagePath(std::string path)
|
|
||||||
{
|
|
||||||
if (!path.empty()) mBitmap = VImageLoader::instance().load(path.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<LayerInfo> model::Composition::layerInfoList() const
|
|
||||||
{
|
|
||||||
if (!mRootLayer || mRootLayer->mChildren.empty()) return {};
|
|
||||||
|
|
||||||
std::vector<LayerInfo> result;
|
|
||||||
|
|
||||||
result.reserve(mRootLayer->mChildren.size());
|
|
||||||
|
|
||||||
for (auto it : mRootLayer->mChildren) {
|
|
||||||
auto layer = static_cast<model::Layer *>(it);
|
|
||||||
result.emplace_back(layer->name(), layer->mInFrame, layer->mOutFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
1148
vendor/github.com/Benau/go_rlottie/lottie_lottiemodel.h
generated
vendored
1148
vendor/github.com/Benau/go_rlottie/lottie_lottiemodel.h
generated
vendored
File diff suppressed because it is too large
Load Diff
2390
vendor/github.com/Benau/go_rlottie/lottie_lottieparser.cpp
generated
vendored
2390
vendor/github.com/Benau/go_rlottie/lottie_lottieparser.cpp
generated
vendored
File diff suppressed because it is too large
Load Diff
0
vendor/github.com/Benau/go_rlottie/lottie_lottieproxymodel.cpp
generated
vendored
0
vendor/github.com/Benau/go_rlottie/lottie_lottieproxymodel.cpp
generated
vendored
284
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_allocators.h
generated
vendored
284
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_allocators.h
generated
vendored
@ -1,284 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ALLOCATORS_H_
|
|
||||||
#define RAPIDJSON_ALLOCATORS_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Allocator
|
|
||||||
|
|
||||||
/*! \class rapidjson::Allocator
|
|
||||||
\brief Concept for allocating, resizing and freeing memory block.
|
|
||||||
|
|
||||||
Note that Malloc() and Realloc() are non-static but Free() is static.
|
|
||||||
|
|
||||||
So if an allocator need to support Free(), it needs to put its pointer in
|
|
||||||
the header of memory block.
|
|
||||||
|
|
||||||
\code
|
|
||||||
concept Allocator {
|
|
||||||
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
|
|
||||||
|
|
||||||
// Allocate a memory block.
|
|
||||||
// \param size of the memory block in bytes.
|
|
||||||
// \returns pointer to the memory block.
|
|
||||||
void* Malloc(size_t size);
|
|
||||||
|
|
||||||
// Resize a memory block.
|
|
||||||
// \param originalPtr The pointer to current memory block. Null pointer is permitted.
|
|
||||||
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
|
|
||||||
// \param newSize the new size in bytes.
|
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
|
|
||||||
|
|
||||||
// Free a memory block.
|
|
||||||
// \param pointer to the memory block. Null pointer is permitted.
|
|
||||||
static void Free(void *ptr);
|
|
||||||
};
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief User-defined kDefaultChunkCapacity definition.
|
|
||||||
|
|
||||||
User can define this as any \c size that is a power of 2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
|
|
||||||
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CrtAllocator
|
|
||||||
|
|
||||||
//! C-runtime library allocator.
|
|
||||||
/*! This class is just wrapper for standard C library memory routines.
|
|
||||||
\note implements Allocator concept
|
|
||||||
*/
|
|
||||||
class CrtAllocator {
|
|
||||||
public:
|
|
||||||
static const bool kNeedFree = true;
|
|
||||||
void* Malloc(size_t size) {
|
|
||||||
if (size) // behavior of malloc(0) is implementation defined.
|
|
||||||
return RAPIDJSON_MALLOC(size);
|
|
||||||
else
|
|
||||||
return NULL; // standardize to returning NULL.
|
|
||||||
}
|
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
|
||||||
(void)originalSize;
|
|
||||||
if (newSize == 0) {
|
|
||||||
RAPIDJSON_FREE(originalPtr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return RAPIDJSON_REALLOC(originalPtr, newSize);
|
|
||||||
}
|
|
||||||
static void Free(void *ptr) { RAPIDJSON_FREE(ptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// MemoryPoolAllocator
|
|
||||||
|
|
||||||
//! Default memory allocator used by the parser and DOM.
|
|
||||||
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
|
|
||||||
|
|
||||||
It does not free memory blocks. And Realloc() only allocate new memory.
|
|
||||||
|
|
||||||
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
|
|
||||||
|
|
||||||
User may also supply a buffer as the first chunk.
|
|
||||||
|
|
||||||
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
|
|
||||||
|
|
||||||
The user-buffer is not deallocated by this allocator.
|
|
||||||
|
|
||||||
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
|
|
||||||
\note implements Allocator concept
|
|
||||||
*/
|
|
||||||
template <typename BaseAllocator = CrtAllocator>
|
|
||||||
class MemoryPoolAllocator {
|
|
||||||
public:
|
|
||||||
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
|
|
||||||
|
|
||||||
//! Constructor with chunkSize.
|
|
||||||
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
|
||||||
\param baseAllocator The allocator for allocating memory chunks.
|
|
||||||
*/
|
|
||||||
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
|
||||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Constructor with user-supplied buffer.
|
|
||||||
/*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
|
|
||||||
|
|
||||||
The user buffer will not be deallocated when this allocator is destructed.
|
|
||||||
|
|
||||||
\param buffer User supplied buffer.
|
|
||||||
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
|
|
||||||
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
|
||||||
\param baseAllocator The allocator for allocating memory chunks.
|
|
||||||
*/
|
|
||||||
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
|
||||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
|
||||||
{
|
|
||||||
RAPIDJSON_ASSERT(buffer != 0);
|
|
||||||
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
|
||||||
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
|
|
||||||
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
|
||||||
chunkHead_->size = 0;
|
|
||||||
chunkHead_->next = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Destructor.
|
|
||||||
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
|
|
||||||
*/
|
|
||||||
~MemoryPoolAllocator() {
|
|
||||||
Clear();
|
|
||||||
RAPIDJSON_DELETE(ownBaseAllocator_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
|
||||||
void Clear() {
|
|
||||||
while (chunkHead_ && chunkHead_ != userBuffer_) {
|
|
||||||
ChunkHeader* next = chunkHead_->next;
|
|
||||||
baseAllocator_->Free(chunkHead_);
|
|
||||||
chunkHead_ = next;
|
|
||||||
}
|
|
||||||
if (chunkHead_ && chunkHead_ == userBuffer_)
|
|
||||||
chunkHead_->size = 0; // Clear user buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Computes the total capacity of allocated memory chunks.
|
|
||||||
/*! \return total capacity in bytes.
|
|
||||||
*/
|
|
||||||
size_t Capacity() const {
|
|
||||||
size_t capacity = 0;
|
|
||||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
|
||||||
capacity += c->capacity;
|
|
||||||
return capacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Computes the memory blocks allocated.
|
|
||||||
/*! \return total used bytes.
|
|
||||||
*/
|
|
||||||
size_t Size() const {
|
|
||||||
size_t size = 0;
|
|
||||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
|
||||||
size += c->size;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Allocates a memory block. (concept Allocator)
|
|
||||||
void* Malloc(size_t size) {
|
|
||||||
if (!size)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
size = RAPIDJSON_ALIGN(size);
|
|
||||||
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
|
|
||||||
if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
|
|
||||||
chunkHead_->size += size;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Resizes a memory block (concept Allocator)
|
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
|
||||||
if (originalPtr == 0)
|
|
||||||
return Malloc(newSize);
|
|
||||||
|
|
||||||
if (newSize == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
originalSize = RAPIDJSON_ALIGN(originalSize);
|
|
||||||
newSize = RAPIDJSON_ALIGN(newSize);
|
|
||||||
|
|
||||||
// Do not shrink if new size is smaller than original
|
|
||||||
if (originalSize >= newSize)
|
|
||||||
return originalPtr;
|
|
||||||
|
|
||||||
// Simply expand it if it is the last allocation and there is sufficient space
|
|
||||||
if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
|
|
||||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
|
||||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
|
||||||
chunkHead_->size += increment;
|
|
||||||
return originalPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Realloc process: allocate and copy memory, do not free original buffer.
|
|
||||||
if (void* newBuffer = Malloc(newSize)) {
|
|
||||||
if (originalSize)
|
|
||||||
std::memcpy(newBuffer, originalPtr, originalSize);
|
|
||||||
return newBuffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Frees a memory block (concept Allocator)
|
|
||||||
static void Free(void *ptr) { (void)ptr; } // Do nothing
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! Copy constructor is not permitted.
|
|
||||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
|
|
||||||
//! Copy assignment operator is not permitted.
|
|
||||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
|
|
||||||
|
|
||||||
//! Creates a new chunk.
|
|
||||||
/*! \param capacity Capacity of the chunk in bytes.
|
|
||||||
\return true if success.
|
|
||||||
*/
|
|
||||||
bool AddChunk(size_t capacity) {
|
|
||||||
if (!baseAllocator_)
|
|
||||||
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
|
|
||||||
if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
|
|
||||||
chunk->capacity = capacity;
|
|
||||||
chunk->size = 0;
|
|
||||||
chunk->next = chunkHead_;
|
|
||||||
chunkHead_ = chunk;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
|
|
||||||
|
|
||||||
//! Chunk header for perpending to each chunk.
|
|
||||||
/*! Chunks are stored as a singly linked list.
|
|
||||||
*/
|
|
||||||
struct ChunkHeader {
|
|
||||||
size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
|
|
||||||
size_t size; //!< Current size of allocated memory in bytes.
|
|
||||||
ChunkHeader *next; //!< Next chunk in the linked list.
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
|
||||||
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
|
||||||
void *userBuffer_; //!< User supplied buffer.
|
|
||||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
|
||||||
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
|
||||||
};
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_ENCODINGS_H_
|
|
78
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_cursorstreamwrapper.h
generated
vendored
78
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_cursorstreamwrapper.h
generated
vendored
@ -1,78 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_
|
|
||||||
#define RAPIDJSON_CURSORSTREAMWRAPPER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
|
|
||||||
//! Cursor stream wrapper for counting line and column number if error exists.
|
|
||||||
/*!
|
|
||||||
\tparam InputStream Any stream that implements Stream Concept
|
|
||||||
*/
|
|
||||||
template <typename InputStream, typename Encoding = UTF8<> >
|
|
||||||
class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
|
|
||||||
public:
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
CursorStreamWrapper(InputStream& is):
|
|
||||||
GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
|
|
||||||
|
|
||||||
// counting line and column number
|
|
||||||
Ch Take() {
|
|
||||||
Ch ch = this->is_.Take();
|
|
||||||
if(ch == '\n') {
|
|
||||||
line_ ++;
|
|
||||||
col_ = 0;
|
|
||||||
} else {
|
|
||||||
col_ ++;
|
|
||||||
}
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the error line number, if error exists.
|
|
||||||
size_t GetLine() const { return line_; }
|
|
||||||
//! Get the error column number, if error exists.
|
|
||||||
size_t GetColumn() const { return col_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t line_; //!< Current Line
|
|
||||||
size_t col_; //!< Current Column
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_
|
|
2732
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_document.h
generated
vendored
2732
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_document.h
generated
vendored
File diff suppressed because it is too large
Load Diff
299
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_encodedstream.h
generated
vendored
299
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_encodedstream.h
generated
vendored
@ -1,299 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
|
|
||||||
#define RAPIDJSON_ENCODEDSTREAM_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include "lottie_rapidjson_memorystream.h"
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Input byte stream wrapper with a statically bound encoding.
|
|
||||||
/*!
|
|
||||||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
|
||||||
\tparam InputByteStream Type of input byte stream. For example, FileReadStream.
|
|
||||||
*/
|
|
||||||
template <typename Encoding, typename InputByteStream>
|
|
||||||
class EncodedInputStream {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
public:
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
EncodedInputStream(InputByteStream& is) : is_(is) {
|
|
||||||
current_ = Encoding::TakeBOM(is_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ch Peek() const { return current_; }
|
|
||||||
Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
|
|
||||||
size_t Tell() const { return is_.Tell(); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
EncodedInputStream(const EncodedInputStream&);
|
|
||||||
EncodedInputStream& operator=(const EncodedInputStream&);
|
|
||||||
|
|
||||||
InputByteStream& is_;
|
|
||||||
Ch current_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Specialized for UTF8 MemoryStream.
|
|
||||||
template <>
|
|
||||||
class EncodedInputStream<UTF8<>, MemoryStream> {
|
|
||||||
public:
|
|
||||||
typedef UTF8<>::Ch Ch;
|
|
||||||
|
|
||||||
EncodedInputStream(MemoryStream& is) : is_(is) {
|
|
||||||
if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take();
|
|
||||||
if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take();
|
|
||||||
if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take();
|
|
||||||
}
|
|
||||||
Ch Peek() const { return is_.Peek(); }
|
|
||||||
Ch Take() { return is_.Take(); }
|
|
||||||
size_t Tell() const { return is_.Tell(); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
void Put(Ch) {}
|
|
||||||
void Flush() {}
|
|
||||||
Ch* PutBegin() { return 0; }
|
|
||||||
size_t PutEnd(Ch*) { return 0; }
|
|
||||||
|
|
||||||
MemoryStream& is_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
EncodedInputStream(const EncodedInputStream&);
|
|
||||||
EncodedInputStream& operator=(const EncodedInputStream&);
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Output byte stream wrapper with statically bound encoding.
|
|
||||||
/*!
|
|
||||||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
|
||||||
\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
|
|
||||||
*/
|
|
||||||
template <typename Encoding, typename OutputByteStream>
|
|
||||||
class EncodedOutputStream {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
public:
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) {
|
|
||||||
if (putBOM)
|
|
||||||
Encoding::PutBOM(os_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Put(Ch c) { Encoding::Put(os_, c); }
|
|
||||||
void Flush() { os_.Flush(); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
|
||||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
EncodedOutputStream(const EncodedOutputStream&);
|
|
||||||
EncodedOutputStream& operator=(const EncodedOutputStream&);
|
|
||||||
|
|
||||||
OutputByteStream& os_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
|
|
||||||
|
|
||||||
//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
|
|
||||||
/*!
|
|
||||||
\tparam CharType Type of character for reading.
|
|
||||||
\tparam InputByteStream type of input byte stream to be wrapped.
|
|
||||||
*/
|
|
||||||
template <typename CharType, typename InputByteStream>
|
|
||||||
class AutoUTFInputStream {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
public:
|
|
||||||
typedef CharType Ch;
|
|
||||||
|
|
||||||
//! Constructor.
|
|
||||||
/*!
|
|
||||||
\param is input stream to be wrapped.
|
|
||||||
\param type UTF encoding type if it is not detected from the stream.
|
|
||||||
*/
|
|
||||||
AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
|
|
||||||
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
|
|
||||||
DetectType();
|
|
||||||
static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
|
|
||||||
takeFunc_ = f[type_];
|
|
||||||
current_ = takeFunc_(*is_);
|
|
||||||
}
|
|
||||||
|
|
||||||
UTFType GetType() const { return type_; }
|
|
||||||
bool HasBOM() const { return hasBOM_; }
|
|
||||||
|
|
||||||
Ch Peek() const { return current_; }
|
|
||||||
Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
|
|
||||||
size_t Tell() const { return is_->Tell(); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoUTFInputStream(const AutoUTFInputStream&);
|
|
||||||
AutoUTFInputStream& operator=(const AutoUTFInputStream&);
|
|
||||||
|
|
||||||
// Detect encoding type with BOM or RFC 4627
|
|
||||||
void DetectType() {
|
|
||||||
// BOM (Byte Order Mark):
|
|
||||||
// 00 00 FE FF UTF-32BE
|
|
||||||
// FF FE 00 00 UTF-32LE
|
|
||||||
// FE FF UTF-16BE
|
|
||||||
// FF FE UTF-16LE
|
|
||||||
// EF BB BF UTF-8
|
|
||||||
|
|
||||||
const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
|
|
||||||
if (!c)
|
|
||||||
return;
|
|
||||||
|
|
||||||
unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
|
|
||||||
hasBOM_ = false;
|
|
||||||
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
|
||||||
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
|
||||||
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
|
||||||
else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
|
||||||
else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); }
|
|
||||||
|
|
||||||
// RFC 4627: Section 3
|
|
||||||
// "Since the first two characters of a JSON text will always be ASCII
|
|
||||||
// characters [RFC0020], it is possible to determine whether an octet
|
|
||||||
// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
|
|
||||||
// at the pattern of nulls in the first four octets."
|
|
||||||
// 00 00 00 xx UTF-32BE
|
|
||||||
// 00 xx 00 xx UTF-16BE
|
|
||||||
// xx 00 00 00 UTF-32LE
|
|
||||||
// xx 00 xx 00 UTF-16LE
|
|
||||||
// xx xx xx xx UTF-8
|
|
||||||
|
|
||||||
if (!hasBOM_) {
|
|
||||||
int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
|
|
||||||
switch (pattern) {
|
|
||||||
case 0x08: type_ = kUTF32BE; break;
|
|
||||||
case 0x0A: type_ = kUTF16BE; break;
|
|
||||||
case 0x01: type_ = kUTF32LE; break;
|
|
||||||
case 0x05: type_ = kUTF16LE; break;
|
|
||||||
case 0x0F: type_ = kUTF8; break;
|
|
||||||
default: break; // Use type defined by user.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
|
||||||
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
|
||||||
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef Ch (*TakeFunc)(InputByteStream& is);
|
|
||||||
InputByteStream* is_;
|
|
||||||
UTFType type_;
|
|
||||||
Ch current_;
|
|
||||||
TakeFunc takeFunc_;
|
|
||||||
bool hasBOM_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
|
|
||||||
/*!
|
|
||||||
\tparam CharType Type of character for writing.
|
|
||||||
\tparam OutputByteStream type of output byte stream to be wrapped.
|
|
||||||
*/
|
|
||||||
template <typename CharType, typename OutputByteStream>
|
|
||||||
class AutoUTFOutputStream {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
public:
|
|
||||||
typedef CharType Ch;
|
|
||||||
|
|
||||||
//! Constructor.
|
|
||||||
/*!
|
|
||||||
\param os output stream to be wrapped.
|
|
||||||
\param type UTF encoding type.
|
|
||||||
\param putBOM Whether to write BOM at the beginning of the stream.
|
|
||||||
*/
|
|
||||||
AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
|
|
||||||
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
|
|
||||||
|
|
||||||
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
|
||||||
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
|
||||||
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
|
||||||
|
|
||||||
static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
|
|
||||||
putFunc_ = f[type_];
|
|
||||||
|
|
||||||
if (putBOM)
|
|
||||||
PutBOM();
|
|
||||||
}
|
|
||||||
|
|
||||||
UTFType GetType() const { return type_; }
|
|
||||||
|
|
||||||
void Put(Ch c) { putFunc_(*os_, c); }
|
|
||||||
void Flush() { os_->Flush(); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
|
||||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoUTFOutputStream(const AutoUTFOutputStream&);
|
|
||||||
AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);
|
|
||||||
|
|
||||||
void PutBOM() {
|
|
||||||
typedef void (*PutBOMFunc)(OutputByteStream&);
|
|
||||||
static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
|
|
||||||
f[type_](*os_);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void (*PutFunc)(OutputByteStream&, Ch);
|
|
||||||
|
|
||||||
OutputByteStream* os_;
|
|
||||||
UTFType type_;
|
|
||||||
PutFunc putFunc_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef RAPIDJSON_ENCODINGS_FUNC
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_FILESTREAM_H_
|
|
716
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_encodings.h
generated
vendored
716
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_encodings.h
generated
vendored
@ -1,716 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ENCODINGS_H_
|
|
||||||
#define RAPIDJSON_ENCODINGS_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
|
|
||||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
RAPIDJSON_DIAG_OFF(overflow)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Encoding
|
|
||||||
|
|
||||||
/*! \class rapidjson::Encoding
|
|
||||||
\brief Concept for encoding of Unicode characters.
|
|
||||||
|
|
||||||
\code
|
|
||||||
concept Encoding {
|
|
||||||
typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition.
|
|
||||||
|
|
||||||
enum { supportUnicode = 1 }; // or 0 if not supporting unicode
|
|
||||||
|
|
||||||
//! \brief Encode a Unicode codepoint to an output stream.
|
|
||||||
//! \param os Output stream.
|
|
||||||
//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void Encode(OutputStream& os, unsigned codepoint);
|
|
||||||
|
|
||||||
//! \brief Decode a Unicode codepoint from an input stream.
|
|
||||||
//! \param is Input stream.
|
|
||||||
//! \param codepoint Output of the unicode codepoint.
|
|
||||||
//! \return true if a valid codepoint can be decoded from the stream.
|
|
||||||
template <typename InputStream>
|
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint);
|
|
||||||
|
|
||||||
//! \brief Validate one Unicode codepoint from an encoded stream.
|
|
||||||
//! \param is Input stream to obtain codepoint.
|
|
||||||
//! \param os Output for copying one codepoint.
|
|
||||||
//! \return true if it is valid.
|
|
||||||
//! \note This function just validating and copying the codepoint without actually decode it.
|
|
||||||
template <typename InputStream, typename OutputStream>
|
|
||||||
static bool Validate(InputStream& is, OutputStream& os);
|
|
||||||
|
|
||||||
// The following functions are deal with byte streams.
|
|
||||||
|
|
||||||
//! Take a character from input byte stream, skip BOM if exist.
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is);
|
|
||||||
|
|
||||||
//! Take a character from input byte stream.
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static Ch Take(InputByteStream& is);
|
|
||||||
|
|
||||||
//! Put BOM to output byte stream.
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os);
|
|
||||||
|
|
||||||
//! Put a character to output byte stream.
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, Ch c);
|
|
||||||
};
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// UTF8
|
|
||||||
|
|
||||||
//! UTF-8 encoding.
|
|
||||||
/*! http://en.wikipedia.org/wiki/UTF-8
|
|
||||||
http://tools.ietf.org/html/rfc3629
|
|
||||||
\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.
|
|
||||||
\note implements Encoding concept
|
|
||||||
*/
|
|
||||||
template<typename CharType = char>
|
|
||||||
struct UTF8 {
|
|
||||||
typedef CharType Ch;
|
|
||||||
|
|
||||||
enum { supportUnicode = 1 };
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
|
||||||
if (codepoint <= 0x7F)
|
|
||||||
os.Put(static_cast<Ch>(codepoint & 0xFF));
|
|
||||||
else if (codepoint <= 0x7FF) {
|
|
||||||
os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
|
|
||||||
os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
|
|
||||||
}
|
|
||||||
else if (codepoint <= 0xFFFF) {
|
|
||||||
os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
|
|
||||||
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
|
||||||
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
|
||||||
os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
|
|
||||||
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
|
|
||||||
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
|
||||||
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
|
||||||
if (codepoint <= 0x7F)
|
|
||||||
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
|
|
||||||
else if (codepoint <= 0x7FF) {
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
|
|
||||||
}
|
|
||||||
else if (codepoint <= 0xFFFF) {
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
|
||||||
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
|
||||||
#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
|
|
||||||
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
|
||||||
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
|
|
||||||
typename InputStream::Ch c = is.Take();
|
|
||||||
if (!(c & 0x80)) {
|
|
||||||
*codepoint = static_cast<unsigned char>(c);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char type = GetRange(static_cast<unsigned char>(c));
|
|
||||||
if (type >= 32) {
|
|
||||||
*codepoint = 0;
|
|
||||||
} else {
|
|
||||||
*codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
|
|
||||||
}
|
|
||||||
bool result = true;
|
|
||||||
switch (type) {
|
|
||||||
case 2: RAPIDJSON_TAIL(); return result;
|
|
||||||
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
#undef RAPIDJSON_COPY
|
|
||||||
#undef RAPIDJSON_TRANS
|
|
||||||
#undef RAPIDJSON_TAIL
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream, typename OutputStream>
|
|
||||||
static bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
#define RAPIDJSON_COPY() os.Put(c = is.Take())
|
|
||||||
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
|
||||||
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
|
|
||||||
Ch c;
|
|
||||||
RAPIDJSON_COPY();
|
|
||||||
if (!(c & 0x80))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bool result = true;
|
|
||||||
switch (GetRange(static_cast<unsigned char>(c))) {
|
|
||||||
case 2: RAPIDJSON_TAIL(); return result;
|
|
||||||
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
|
|
||||||
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
#undef RAPIDJSON_COPY
|
|
||||||
#undef RAPIDJSON_TRANS
|
|
||||||
#undef RAPIDJSON_TAIL
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char GetRange(unsigned char c) {
|
|
||||||
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
|
||||||
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
|
|
||||||
static const unsigned char type[] = {
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
|
|
||||||
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
|
||||||
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
|
||||||
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
|
||||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
||||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
|
||||||
};
|
|
||||||
return type[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
typename InputByteStream::Ch c = Take(is);
|
|
||||||
if (static_cast<unsigned char>(c) != 0xEFu) return c;
|
|
||||||
c = is.Take();
|
|
||||||
if (static_cast<unsigned char>(c) != 0xBBu) return c;
|
|
||||||
c = is.Take();
|
|
||||||
if (static_cast<unsigned char>(c) != 0xBFu) return c;
|
|
||||||
c = is.Take();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static Ch Take(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
return static_cast<Ch>(is.Take());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, Ch c) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(c));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// UTF16
|
|
||||||
|
|
||||||
//! UTF-16 encoding.
|
|
||||||
/*! http://en.wikipedia.org/wiki/UTF-16
|
|
||||||
http://tools.ietf.org/html/rfc2781
|
|
||||||
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
|
|
||||||
\note implements Encoding concept
|
|
||||||
|
|
||||||
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
|
|
||||||
For streaming, use UTF16LE and UTF16BE, which handle endianness.
|
|
||||||
*/
|
|
||||||
template<typename CharType = wchar_t>
|
|
||||||
struct UTF16 {
|
|
||||||
typedef CharType Ch;
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
|
|
||||||
|
|
||||||
enum { supportUnicode = 1 };
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
|
||||||
if (codepoint <= 0xFFFF) {
|
|
||||||
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
|
|
||||||
os.Put(static_cast<typename OutputStream::Ch>(codepoint));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
|
||||||
unsigned v = codepoint - 0x10000;
|
|
||||||
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
|
|
||||||
os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
|
||||||
if (codepoint <= 0xFFFF) {
|
|
||||||
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
|
|
||||||
PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
|
||||||
unsigned v = codepoint - 0x10000;
|
|
||||||
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
|
|
||||||
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
|
||||||
typename InputStream::Ch c = is.Take();
|
|
||||||
if (c < 0xD800 || c > 0xDFFF) {
|
|
||||||
*codepoint = static_cast<unsigned>(c);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (c <= 0xDBFF) {
|
|
||||||
*codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
|
|
||||||
c = is.Take();
|
|
||||||
*codepoint |= (static_cast<unsigned>(c) & 0x3FF);
|
|
||||||
*codepoint += 0x10000;
|
|
||||||
return c >= 0xDC00 && c <= 0xDFFF;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream, typename OutputStream>
|
|
||||||
static bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
|
||||||
typename InputStream::Ch c;
|
|
||||||
os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
|
|
||||||
if (c < 0xD800 || c > 0xDFFF)
|
|
||||||
return true;
|
|
||||||
else if (c <= 0xDBFF) {
|
|
||||||
os.Put(c = is.Take());
|
|
||||||
return c >= 0xDC00 && c <= 0xDFFF;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! UTF-16 little endian encoding.
|
|
||||||
template<typename CharType = wchar_t>
|
|
||||||
struct UTF16LE : UTF16<CharType> {
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
CharType c = Take(is);
|
|
||||||
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType Take(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
unsigned c = static_cast<uint8_t>(is.Take());
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
|
||||||
return static_cast<CharType>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, CharType c) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! UTF-16 big endian encoding.
|
|
||||||
template<typename CharType = wchar_t>
|
|
||||||
struct UTF16BE : UTF16<CharType> {
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
CharType c = Take(is);
|
|
||||||
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType Take(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
|
|
||||||
return static_cast<CharType>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, CharType c) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// UTF32
|
|
||||||
|
|
||||||
//! UTF-32 encoding.
|
|
||||||
/*! http://en.wikipedia.org/wiki/UTF-32
|
|
||||||
\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
|
|
||||||
\note implements Encoding concept
|
|
||||||
|
|
||||||
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
|
|
||||||
For streaming, use UTF32LE and UTF32BE, which handle endianness.
|
|
||||||
*/
|
|
||||||
template<typename CharType = unsigned>
|
|
||||||
struct UTF32 {
|
|
||||||
typedef CharType Ch;
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
|
|
||||||
|
|
||||||
enum { supportUnicode = 1 };
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
|
||||||
os.Put(codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
|
||||||
PutUnsafe(os, codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
|
|
||||||
Ch c = is.Take();
|
|
||||||
*codepoint = c;
|
|
||||||
return c <= 0x10FFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream, typename OutputStream>
|
|
||||||
static bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
|
|
||||||
Ch c;
|
|
||||||
os.Put(c = is.Take());
|
|
||||||
return c <= 0x10FFFF;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! UTF-32 little endian enocoding.
|
|
||||||
template<typename CharType = unsigned>
|
|
||||||
struct UTF32LE : UTF32<CharType> {
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
CharType c = Take(is);
|
|
||||||
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType Take(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
unsigned c = static_cast<uint8_t>(is.Take());
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
|
|
||||||
return static_cast<CharType>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, CharType c) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! UTF-32 big endian encoding.
|
|
||||||
template<typename CharType = unsigned>
|
|
||||||
struct UTF32BE : UTF32<CharType> {
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
CharType c = Take(is);
|
|
||||||
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType Take(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
|
||||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
|
|
||||||
return static_cast<CharType>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, CharType c) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ASCII
|
|
||||||
|
|
||||||
//! ASCII encoding.
|
|
||||||
/*! http://en.wikipedia.org/wiki/ASCII
|
|
||||||
\tparam CharType Code unit for storing 7-bit ASCII data. Default is char.
|
|
||||||
\note implements Encoding concept
|
|
||||||
*/
|
|
||||||
template<typename CharType = char>
|
|
||||||
struct ASCII {
|
|
||||||
typedef CharType Ch;
|
|
||||||
|
|
||||||
enum { supportUnicode = 0 };
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x7F);
|
|
||||||
os.Put(static_cast<Ch>(codepoint & 0xFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
|
||||||
RAPIDJSON_ASSERT(codepoint <= 0x7F);
|
|
||||||
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
|
||||||
uint8_t c = static_cast<uint8_t>(is.Take());
|
|
||||||
*codepoint = c;
|
|
||||||
return c <= 0X7F;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream, typename OutputStream>
|
|
||||||
static bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
uint8_t c = static_cast<uint8_t>(is.Take());
|
|
||||||
os.Put(static_cast<typename OutputStream::Ch>(c));
|
|
||||||
return c <= 0x7F;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static CharType TakeBOM(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
uint8_t c = static_cast<uint8_t>(Take(is));
|
|
||||||
return static_cast<Ch>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputByteStream>
|
|
||||||
static Ch Take(InputByteStream& is) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
|
||||||
return static_cast<Ch>(is.Take());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void PutBOM(OutputByteStream& os) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
(void)os;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputByteStream>
|
|
||||||
static void Put(OutputByteStream& os, Ch c) {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
|
||||||
os.Put(static_cast<typename OutputByteStream::Ch>(c));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// AutoUTF
|
|
||||||
|
|
||||||
//! Runtime-specified UTF encoding type of a stream.
|
|
||||||
enum UTFType {
|
|
||||||
kUTF8 = 0, //!< UTF-8.
|
|
||||||
kUTF16LE = 1, //!< UTF-16 little endian.
|
|
||||||
kUTF16BE = 2, //!< UTF-16 big endian.
|
|
||||||
kUTF32LE = 3, //!< UTF-32 little endian.
|
|
||||||
kUTF32BE = 4 //!< UTF-32 big endian.
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.
|
|
||||||
/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().
|
|
||||||
*/
|
|
||||||
template<typename CharType>
|
|
||||||
struct AutoUTF {
|
|
||||||
typedef CharType Ch;
|
|
||||||
|
|
||||||
enum { supportUnicode = 1 };
|
|
||||||
|
|
||||||
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) {
|
|
||||||
typedef void (*EncodeFunc)(OutputStream&, unsigned);
|
|
||||||
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
|
|
||||||
(*f[os.GetType()])(os, codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
|
||||||
typedef void (*EncodeFunc)(OutputStream&, unsigned);
|
|
||||||
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
|
|
||||||
(*f[os.GetType()])(os, codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) {
|
|
||||||
typedef bool (*DecodeFunc)(InputStream&, unsigned*);
|
|
||||||
static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
|
|
||||||
return (*f[is.GetType()])(is, codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
|
|
||||||
static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
|
|
||||||
return (*f[is.GetType()])(is, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef RAPIDJSON_ENCODINGS_FUNC
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Transcoder
|
|
||||||
|
|
||||||
//! Encoding conversion.
|
|
||||||
template<typename SourceEncoding, typename TargetEncoding>
|
|
||||||
struct Transcoder {
|
|
||||||
//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
|
|
||||||
template<typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
|
|
||||||
unsigned codepoint;
|
|
||||||
if (!SourceEncoding::Decode(is, &codepoint))
|
|
||||||
return false;
|
|
||||||
TargetEncoding::Encode(os, codepoint);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
|
|
||||||
unsigned codepoint;
|
|
||||||
if (!SourceEncoding::Decode(is, &codepoint))
|
|
||||||
return false;
|
|
||||||
TargetEncoding::EncodeUnsafe(os, codepoint);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Validate one Unicode codepoint from an encoded stream.
|
|
||||||
template<typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
return Transcode(is, os); // Since source/target encoding is different, must transcode.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Forward declaration.
|
|
||||||
template<typename Stream>
|
|
||||||
inline void PutUnsafe(Stream& stream, typename Stream::Ch c);
|
|
||||||
|
|
||||||
//! Specialization of Transcoder with same source and target encoding.
|
|
||||||
template<typename Encoding>
|
|
||||||
struct Transcoder<Encoding, Encoding> {
|
|
||||||
template<typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
|
|
||||||
os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
|
|
||||||
PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename InputStream, typename OutputStream>
|
|
||||||
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
|
|
||||||
return Encoding::Validate(is, os); // source/target encoding are the same
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__))
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_ENCODINGS_H_
|
|
74
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_error_en.h
generated
vendored
74
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_error_en.h
generated
vendored
@ -1,74 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ERROR_EN_H_
|
|
||||||
#define RAPIDJSON_ERROR_EN_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_error_error.h"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
|
||||||
RAPIDJSON_DIAG_OFF(covered-switch-default)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Maps error code of parsing into error message.
|
|
||||||
/*!
|
|
||||||
\ingroup RAPIDJSON_ERRORS
|
|
||||||
\param parseErrorCode Error code obtained in parsing.
|
|
||||||
\return the error message.
|
|
||||||
\note User can make a copy of this function for localization.
|
|
||||||
Using switch-case is safer for future modification of error codes.
|
|
||||||
*/
|
|
||||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
|
|
||||||
switch (parseErrorCode) {
|
|
||||||
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
|
||||||
|
|
||||||
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
|
||||||
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
|
||||||
|
|
||||||
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
|
||||||
|
|
||||||
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
|
||||||
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
|
||||||
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
|
||||||
|
|
||||||
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
|
||||||
|
|
||||||
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
|
||||||
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
|
|
||||||
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
|
|
||||||
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
|
|
||||||
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
|
|
||||||
|
|
||||||
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
|
|
||||||
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
|
|
||||||
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
|
|
||||||
|
|
||||||
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
|
||||||
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
|
||||||
|
|
||||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_ERROR_EN_H_
|
|
161
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_error_error.h
generated
vendored
161
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_error_error.h
generated
vendored
@ -1,161 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ERROR_ERROR_H_
|
|
||||||
#define RAPIDJSON_ERROR_ERROR_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \file error.h */
|
|
||||||
|
|
||||||
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_ERROR_CHARTYPE
|
|
||||||
|
|
||||||
//! Character type of error messages.
|
|
||||||
/*! \ingroup RAPIDJSON_ERRORS
|
|
||||||
The default character type is \c char.
|
|
||||||
On Windows, user can define this macro as \c TCHAR for supporting both
|
|
||||||
unicode/non-unicode settings.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_ERROR_CHARTYPE
|
|
||||||
#define RAPIDJSON_ERROR_CHARTYPE char
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_ERROR_STRING
|
|
||||||
|
|
||||||
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
|
||||||
/*! \ingroup RAPIDJSON_ERRORS
|
|
||||||
By default this conversion macro does nothing.
|
|
||||||
On Windows, user can define this macro as \c _T(x) for supporting both
|
|
||||||
unicode/non-unicode settings.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_ERROR_STRING
|
|
||||||
#define RAPIDJSON_ERROR_STRING(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ParseErrorCode
|
|
||||||
|
|
||||||
//! Error code of parsing.
|
|
||||||
/*! \ingroup RAPIDJSON_ERRORS
|
|
||||||
\see GenericReader::Parse, GenericReader::GetParseErrorCode
|
|
||||||
*/
|
|
||||||
enum ParseErrorCode {
|
|
||||||
kParseErrorNone = 0, //!< No error.
|
|
||||||
|
|
||||||
kParseErrorDocumentEmpty, //!< The document is empty.
|
|
||||||
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
|
|
||||||
|
|
||||||
kParseErrorValueInvalid, //!< Invalid value.
|
|
||||||
|
|
||||||
kParseErrorObjectMissName, //!< Missing a name for object member.
|
|
||||||
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
|
|
||||||
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
|
|
||||||
|
|
||||||
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
|
|
||||||
|
|
||||||
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
|
|
||||||
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
|
|
||||||
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
|
|
||||||
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
|
|
||||||
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
|
|
||||||
|
|
||||||
kParseErrorNumberTooBig, //!< Number too big to be stored in double.
|
|
||||||
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
|
|
||||||
kParseErrorNumberMissExponent, //!< Miss exponent in number.
|
|
||||||
|
|
||||||
kParseErrorTermination, //!< Parsing was terminated.
|
|
||||||
kParseErrorUnspecificSyntaxError //!< Unspecific syntax error.
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Result of parsing (wraps ParseErrorCode)
|
|
||||||
/*!
|
|
||||||
\ingroup RAPIDJSON_ERRORS
|
|
||||||
\code
|
|
||||||
Document doc;
|
|
||||||
ParseResult ok = doc.Parse("[42]");
|
|
||||||
if (!ok) {
|
|
||||||
fprintf(stderr, "JSON parse error: %s (%u)",
|
|
||||||
GetParseError_En(ok.Code()), ok.Offset());
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
\see GenericReader::Parse, GenericDocument::Parse
|
|
||||||
*/
|
|
||||||
struct ParseResult {
|
|
||||||
//!! Unspecified boolean type
|
|
||||||
typedef bool (ParseResult::*BooleanType)() const;
|
|
||||||
public:
|
|
||||||
//! Default constructor, no error.
|
|
||||||
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
|
||||||
//! Constructor to set an error.
|
|
||||||
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
|
|
||||||
|
|
||||||
//! Get the error code.
|
|
||||||
ParseErrorCode Code() const { return code_; }
|
|
||||||
//! Get the error offset, if \ref IsError(), 0 otherwise.
|
|
||||||
size_t Offset() const { return offset_; }
|
|
||||||
|
|
||||||
//! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
|
|
||||||
operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
|
|
||||||
//! Whether the result is an error.
|
|
||||||
bool IsError() const { return code_ != kParseErrorNone; }
|
|
||||||
|
|
||||||
bool operator==(const ParseResult& that) const { return code_ == that.code_; }
|
|
||||||
bool operator==(ParseErrorCode code) const { return code_ == code; }
|
|
||||||
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
|
|
||||||
|
|
||||||
bool operator!=(const ParseResult& that) const { return !(*this == that); }
|
|
||||||
bool operator!=(ParseErrorCode code) const { return !(*this == code); }
|
|
||||||
friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; }
|
|
||||||
|
|
||||||
//! Reset error code.
|
|
||||||
void Clear() { Set(kParseErrorNone); }
|
|
||||||
//! Update error code and offset.
|
|
||||||
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ParseErrorCode code_;
|
|
||||||
size_t offset_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Function pointer type of GetParseError().
|
|
||||||
/*! \ingroup RAPIDJSON_ERRORS
|
|
||||||
|
|
||||||
This is the prototype for \c GetParseError_X(), where \c X is a locale.
|
|
||||||
User can dynamically change locale in runtime, e.g.:
|
|
||||||
\code
|
|
||||||
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
|
|
||||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_ERROR_ERROR_H_
|
|
99
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_filereadstream.h
generated
vendored
99
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_filereadstream.h
generated
vendored
@ -1,99 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_FILEREADSTREAM_H_
|
|
||||||
#define RAPIDJSON_FILEREADSTREAM_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
|
||||||
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! File byte stream for input using fread().
|
|
||||||
/*!
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
class FileReadStream {
|
|
||||||
public:
|
|
||||||
typedef char Ch; //!< Character type (byte).
|
|
||||||
|
|
||||||
//! Constructor.
|
|
||||||
/*!
|
|
||||||
\param fp File pointer opened for read.
|
|
||||||
\param buffer user-supplied buffer.
|
|
||||||
\param bufferSize size of buffer in bytes. Must >=4 bytes.
|
|
||||||
*/
|
|
||||||
FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
|
||||||
RAPIDJSON_ASSERT(fp_ != 0);
|
|
||||||
RAPIDJSON_ASSERT(bufferSize >= 4);
|
|
||||||
Read();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ch Peek() const { return *current_; }
|
|
||||||
Ch Take() { Ch c = *current_; Read(); return c; }
|
|
||||||
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
// For encoding detection only.
|
|
||||||
const Ch* Peek4() const {
|
|
||||||
return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Read() {
|
|
||||||
if (current_ < bufferLast_)
|
|
||||||
++current_;
|
|
||||||
else if (!eof_) {
|
|
||||||
count_ += readCount_;
|
|
||||||
readCount_ = std::fread(buffer_, 1, bufferSize_, fp_);
|
|
||||||
bufferLast_ = buffer_ + readCount_ - 1;
|
|
||||||
current_ = buffer_;
|
|
||||||
|
|
||||||
if (readCount_ < bufferSize_) {
|
|
||||||
buffer_[readCount_] = '\0';
|
|
||||||
++bufferLast_;
|
|
||||||
eof_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::FILE* fp_;
|
|
||||||
Ch *buffer_;
|
|
||||||
size_t bufferSize_;
|
|
||||||
Ch *bufferLast_;
|
|
||||||
Ch *current_;
|
|
||||||
size_t readCount_;
|
|
||||||
size_t count_; //!< Number of characters read
|
|
||||||
bool eof_;
|
|
||||||
};
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_FILESTREAM_H_
|
|
104
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_filewritestream.h
generated
vendored
104
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_filewritestream.h
generated
vendored
@ -1,104 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
|
|
||||||
#define RAPIDJSON_FILEWRITESTREAM_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Wrapper of C file stream for output using fwrite().
|
|
||||||
/*!
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
class FileWriteStream {
|
|
||||||
public:
|
|
||||||
typedef char Ch; //!< Character type. Only support char.
|
|
||||||
|
|
||||||
FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
|
|
||||||
RAPIDJSON_ASSERT(fp_ != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Put(char c) {
|
|
||||||
if (current_ >= bufferEnd_)
|
|
||||||
Flush();
|
|
||||||
|
|
||||||
*current_++ = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PutN(char c, size_t n) {
|
|
||||||
size_t avail = static_cast<size_t>(bufferEnd_ - current_);
|
|
||||||
while (n > avail) {
|
|
||||||
std::memset(current_, c, avail);
|
|
||||||
current_ += avail;
|
|
||||||
Flush();
|
|
||||||
n -= avail;
|
|
||||||
avail = static_cast<size_t>(bufferEnd_ - current_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n > 0) {
|
|
||||||
std::memset(current_, c, n);
|
|
||||||
current_ += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flush() {
|
|
||||||
if (current_ != buffer_) {
|
|
||||||
size_t result = std::fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
|
||||||
if (result < static_cast<size_t>(current_ - buffer_)) {
|
|
||||||
// failure deliberately ignored at this time
|
|
||||||
// added to avoid warn_unused_result build errors
|
|
||||||
}
|
|
||||||
current_ = buffer_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
|
||||||
FileWriteStream(const FileWriteStream&);
|
|
||||||
FileWriteStream& operator=(const FileWriteStream&);
|
|
||||||
|
|
||||||
std::FILE* fp_;
|
|
||||||
char *buffer_;
|
|
||||||
char *bufferEnd_;
|
|
||||||
char *current_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Implement specialized version of PutN() with memset() for better performance.
|
|
||||||
template<>
|
|
||||||
inline void PutN(FileWriteStream& stream, char c, size_t n) {
|
|
||||||
stream.PutN(c, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_FILESTREAM_H_
|
|
151
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_fwd.h
generated
vendored
151
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_fwd.h
generated
vendored
@ -1,151 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_FWD_H_
|
|
||||||
#define RAPIDJSON_FWD_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
// encodings.h
|
|
||||||
|
|
||||||
template<typename CharType> struct UTF8;
|
|
||||||
template<typename CharType> struct UTF16;
|
|
||||||
template<typename CharType> struct UTF16BE;
|
|
||||||
template<typename CharType> struct UTF16LE;
|
|
||||||
template<typename CharType> struct UTF32;
|
|
||||||
template<typename CharType> struct UTF32BE;
|
|
||||||
template<typename CharType> struct UTF32LE;
|
|
||||||
template<typename CharType> struct ASCII;
|
|
||||||
template<typename CharType> struct AutoUTF;
|
|
||||||
|
|
||||||
template<typename SourceEncoding, typename TargetEncoding>
|
|
||||||
struct Transcoder;
|
|
||||||
|
|
||||||
// allocators.h
|
|
||||||
|
|
||||||
class CrtAllocator;
|
|
||||||
|
|
||||||
template <typename BaseAllocator>
|
|
||||||
class MemoryPoolAllocator;
|
|
||||||
|
|
||||||
// stream.h
|
|
||||||
|
|
||||||
template <typename Encoding>
|
|
||||||
struct GenericStringStream;
|
|
||||||
|
|
||||||
typedef GenericStringStream<UTF8<char> > StringStream;
|
|
||||||
|
|
||||||
template <typename Encoding>
|
|
||||||
struct GenericInsituStringStream;
|
|
||||||
|
|
||||||
typedef GenericInsituStringStream<UTF8<char> > InsituStringStream;
|
|
||||||
|
|
||||||
// stringbuffer.h
|
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
|
||||||
class GenericStringBuffer;
|
|
||||||
|
|
||||||
typedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;
|
|
||||||
|
|
||||||
// filereadstream.h
|
|
||||||
|
|
||||||
class FileReadStream;
|
|
||||||
|
|
||||||
// filewritestream.h
|
|
||||||
|
|
||||||
class FileWriteStream;
|
|
||||||
|
|
||||||
// memorybuffer.h
|
|
||||||
|
|
||||||
template <typename Allocator>
|
|
||||||
struct GenericMemoryBuffer;
|
|
||||||
|
|
||||||
typedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;
|
|
||||||
|
|
||||||
// memorystream.h
|
|
||||||
|
|
||||||
struct MemoryStream;
|
|
||||||
|
|
||||||
// reader.h
|
|
||||||
|
|
||||||
template<typename Encoding, typename Derived>
|
|
||||||
struct BaseReaderHandler;
|
|
||||||
|
|
||||||
template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator>
|
|
||||||
class GenericReader;
|
|
||||||
|
|
||||||
typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;
|
|
||||||
|
|
||||||
// writer.h
|
|
||||||
|
|
||||||
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
|
|
||||||
class Writer;
|
|
||||||
|
|
||||||
// prettywriter.h
|
|
||||||
|
|
||||||
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
|
|
||||||
class PrettyWriter;
|
|
||||||
|
|
||||||
// document.h
|
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
|
||||||
class GenericMember;
|
|
||||||
|
|
||||||
template <bool Const, typename Encoding, typename Allocator>
|
|
||||||
class GenericMemberIterator;
|
|
||||||
|
|
||||||
template<typename CharType>
|
|
||||||
struct GenericStringRef;
|
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
|
||||||
class GenericValue;
|
|
||||||
|
|
||||||
typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
|
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator, typename StackAllocator>
|
|
||||||
class GenericDocument;
|
|
||||||
|
|
||||||
typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document;
|
|
||||||
|
|
||||||
// pointer.h
|
|
||||||
|
|
||||||
template <typename ValueType, typename Allocator>
|
|
||||||
class GenericPointer;
|
|
||||||
|
|
||||||
typedef GenericPointer<Value, CrtAllocator> Pointer;
|
|
||||||
|
|
||||||
// schema.h
|
|
||||||
|
|
||||||
template <typename SchemaDocumentType>
|
|
||||||
class IGenericRemoteSchemaDocumentProvider;
|
|
||||||
|
|
||||||
template <typename ValueT, typename Allocator>
|
|
||||||
class GenericSchemaDocument;
|
|
||||||
|
|
||||||
typedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;
|
|
||||||
typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename SchemaDocumentType,
|
|
||||||
typename OutputHandler,
|
|
||||||
typename StateAllocator>
|
|
||||||
class GenericSchemaValidator;
|
|
||||||
|
|
||||||
typedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator;
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_RAPIDJSONFWD_H_
|
|
290
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_biginteger.h
generated
vendored
290
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_biginteger.h
generated
vendored
@ -1,290 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_BIGINTEGER_H_
|
|
||||||
#define RAPIDJSON_BIGINTEGER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
|
||||||
#include <intrin.h> // for _umul128
|
|
||||||
#pragma intrinsic(_umul128)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class BigInteger {
|
|
||||||
public:
|
|
||||||
typedef uint64_t Type;
|
|
||||||
|
|
||||||
BigInteger(const BigInteger& rhs) : count_(rhs.count_) {
|
|
||||||
std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit BigInteger(uint64_t u) : count_(1) {
|
|
||||||
digits_[0] = u;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger(const char* decimals, size_t length) : count_(1) {
|
|
||||||
RAPIDJSON_ASSERT(length > 0);
|
|
||||||
digits_[0] = 0;
|
|
||||||
size_t i = 0;
|
|
||||||
const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19
|
|
||||||
while (length >= kMaxDigitPerIteration) {
|
|
||||||
AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration);
|
|
||||||
length -= kMaxDigitPerIteration;
|
|
||||||
i += kMaxDigitPerIteration;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > 0)
|
|
||||||
AppendDecimal64(decimals + i, decimals + i + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& operator=(const BigInteger &rhs)
|
|
||||||
{
|
|
||||||
if (this != &rhs) {
|
|
||||||
count_ = rhs.count_;
|
|
||||||
std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& operator=(uint64_t u) {
|
|
||||||
digits_[0] = u;
|
|
||||||
count_ = 1;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& operator+=(uint64_t u) {
|
|
||||||
Type backup = digits_[0];
|
|
||||||
digits_[0] += u;
|
|
||||||
for (size_t i = 0; i < count_ - 1; i++) {
|
|
||||||
if (digits_[i] >= backup)
|
|
||||||
return *this; // no carry
|
|
||||||
backup = digits_[i + 1];
|
|
||||||
digits_[i + 1] += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last carry
|
|
||||||
if (digits_[count_ - 1] < backup)
|
|
||||||
PushBack(1);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& operator*=(uint64_t u) {
|
|
||||||
if (u == 0) return *this = 0;
|
|
||||||
if (u == 1) return *this;
|
|
||||||
if (*this == 1) return *this = u;
|
|
||||||
|
|
||||||
uint64_t k = 0;
|
|
||||||
for (size_t i = 0; i < count_; i++) {
|
|
||||||
uint64_t hi;
|
|
||||||
digits_[i] = MulAdd64(digits_[i], u, k, &hi);
|
|
||||||
k = hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k > 0)
|
|
||||||
PushBack(k);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& operator*=(uint32_t u) {
|
|
||||||
if (u == 0) return *this = 0;
|
|
||||||
if (u == 1) return *this;
|
|
||||||
if (*this == 1) return *this = u;
|
|
||||||
|
|
||||||
uint64_t k = 0;
|
|
||||||
for (size_t i = 0; i < count_; i++) {
|
|
||||||
const uint64_t c = digits_[i] >> 32;
|
|
||||||
const uint64_t d = digits_[i] & 0xFFFFFFFF;
|
|
||||||
const uint64_t uc = u * c;
|
|
||||||
const uint64_t ud = u * d;
|
|
||||||
const uint64_t p0 = ud + k;
|
|
||||||
const uint64_t p1 = uc + (p0 >> 32);
|
|
||||||
digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32);
|
|
||||||
k = p1 >> 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k > 0)
|
|
||||||
PushBack(k);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& operator<<=(size_t shift) {
|
|
||||||
if (IsZero() || shift == 0) return *this;
|
|
||||||
|
|
||||||
size_t offset = shift / kTypeBit;
|
|
||||||
size_t interShift = shift % kTypeBit;
|
|
||||||
RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
|
|
||||||
|
|
||||||
if (interShift == 0) {
|
|
||||||
std::memmove(digits_ + offset, digits_, count_ * sizeof(Type));
|
|
||||||
count_ += offset;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
digits_[count_] = 0;
|
|
||||||
for (size_t i = count_; i > 0; i--)
|
|
||||||
digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift));
|
|
||||||
digits_[offset] = digits_[0] << interShift;
|
|
||||||
count_ += offset;
|
|
||||||
if (digits_[count_])
|
|
||||||
count_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::memset(digits_, 0, offset * sizeof(Type));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const BigInteger& rhs) const {
|
|
||||||
return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Type rhs) const {
|
|
||||||
return count_ == 1 && digits_[0] == rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger& MultiplyPow5(unsigned exp) {
|
|
||||||
static const uint32_t kPow5[12] = {
|
|
||||||
5,
|
|
||||||
5 * 5,
|
|
||||||
5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
|
|
||||||
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
|
|
||||||
};
|
|
||||||
if (exp == 0) return *this;
|
|
||||||
for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27
|
|
||||||
for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13
|
|
||||||
if (exp > 0) *this *= kPow5[exp - 1];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute absolute difference of this and rhs.
|
|
||||||
// Assume this != rhs
|
|
||||||
bool Difference(const BigInteger& rhs, BigInteger* out) const {
|
|
||||||
int cmp = Compare(rhs);
|
|
||||||
RAPIDJSON_ASSERT(cmp != 0);
|
|
||||||
const BigInteger *a, *b; // Makes a > b
|
|
||||||
bool ret;
|
|
||||||
if (cmp < 0) { a = &rhs; b = this; ret = true; }
|
|
||||||
else { a = this; b = &rhs; ret = false; }
|
|
||||||
|
|
||||||
Type borrow = 0;
|
|
||||||
for (size_t i = 0; i < a->count_; i++) {
|
|
||||||
Type d = a->digits_[i] - borrow;
|
|
||||||
if (i < b->count_)
|
|
||||||
d -= b->digits_[i];
|
|
||||||
borrow = (d > a->digits_[i]) ? 1 : 0;
|
|
||||||
out->digits_[i] = d;
|
|
||||||
if (d != 0)
|
|
||||||
out->count_ = i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Compare(const BigInteger& rhs) const {
|
|
||||||
if (count_ != rhs.count_)
|
|
||||||
return count_ < rhs.count_ ? -1 : 1;
|
|
||||||
|
|
||||||
for (size_t i = count_; i-- > 0;)
|
|
||||||
if (digits_[i] != rhs.digits_[i])
|
|
||||||
return digits_[i] < rhs.digits_[i] ? -1 : 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetCount() const { return count_; }
|
|
||||||
Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }
|
|
||||||
bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void AppendDecimal64(const char* begin, const char* end) {
|
|
||||||
uint64_t u = ParseUint64(begin, end);
|
|
||||||
if (IsZero())
|
|
||||||
*this = u;
|
|
||||||
else {
|
|
||||||
unsigned exp = static_cast<unsigned>(end - begin);
|
|
||||||
(MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushBack(Type digit) {
|
|
||||||
RAPIDJSON_ASSERT(count_ < kCapacity);
|
|
||||||
digits_[count_++] = digit;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t ParseUint64(const char* begin, const char* end) {
|
|
||||||
uint64_t r = 0;
|
|
||||||
for (const char* p = begin; p != end; ++p) {
|
|
||||||
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
|
|
||||||
r = r * 10u + static_cast<unsigned>(*p - '0');
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume a * b + k < 2^128
|
|
||||||
static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
|
||||||
uint64_t low = _umul128(a, b, outHigh) + k;
|
|
||||||
if (low < k)
|
|
||||||
(*outHigh)++;
|
|
||||||
return low;
|
|
||||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
|
||||||
__extension__ typedef unsigned __int128 uint128;
|
|
||||||
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
|
|
||||||
p += k;
|
|
||||||
*outHigh = static_cast<uint64_t>(p >> 64);
|
|
||||||
return static_cast<uint64_t>(p);
|
|
||||||
#else
|
|
||||||
const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;
|
|
||||||
uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1;
|
|
||||||
x1 += (x0 >> 32); // can't give carry
|
|
||||||
x1 += x2;
|
|
||||||
if (x1 < x2)
|
|
||||||
x3 += (static_cast<uint64_t>(1) << 32);
|
|
||||||
uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);
|
|
||||||
uint64_t hi = x3 + (x1 >> 32);
|
|
||||||
|
|
||||||
lo += k;
|
|
||||||
if (lo < k)
|
|
||||||
hi++;
|
|
||||||
*outHigh = hi;
|
|
||||||
return lo;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000
|
|
||||||
static const size_t kCapacity = kBitCount / sizeof(Type);
|
|
||||||
static const size_t kTypeBit = sizeof(Type) * 8;
|
|
||||||
|
|
||||||
Type digits_[kCapacity];
|
|
||||||
size_t count_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_BIGINTEGER_H_
|
|
71
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_clzll.h
generated
vendored
71
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_clzll.h
generated
vendored
@ -1,71 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_CLZLL_H_
|
|
||||||
#define RAPIDJSON_CLZLL_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(UNDER_CE)
|
|
||||||
#include <intrin.h>
|
|
||||||
#if defined(_WIN64)
|
|
||||||
#pragma intrinsic(_BitScanReverse64)
|
|
||||||
#else
|
|
||||||
#pragma intrinsic(_BitScanReverse)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
inline uint32_t clzll(uint64_t x) {
|
|
||||||
// Passing 0 to __builtin_clzll is UB in GCC and results in an
|
|
||||||
// infinite loop in the software implementation.
|
|
||||||
RAPIDJSON_ASSERT(x != 0);
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(UNDER_CE)
|
|
||||||
unsigned long r = 0;
|
|
||||||
#if defined(_WIN64)
|
|
||||||
_BitScanReverse64(&r, x);
|
|
||||||
#else
|
|
||||||
// Scan the high 32 bits.
|
|
||||||
if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
|
|
||||||
return 63 - (r + 32);
|
|
||||||
|
|
||||||
// Scan the low 32 bits.
|
|
||||||
_BitScanReverse(&r, static_cast<uint32_t>(x & 0xFFFFFFFF));
|
|
||||||
#endif // _WIN64
|
|
||||||
|
|
||||||
return 63 - r;
|
|
||||||
#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
|
|
||||||
// __builtin_clzll wrapper
|
|
||||||
return static_cast<uint32_t>(__builtin_clzll(x));
|
|
||||||
#else
|
|
||||||
// naive version
|
|
||||||
uint32_t r = 0;
|
|
||||||
while (!(x & (static_cast<uint64_t>(1) << 63))) {
|
|
||||||
x <<= 1;
|
|
||||||
++r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
#endif // _MSC_VER
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_CLZLL_H_
|
|
257
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_diyfp.h
generated
vendored
257
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_diyfp.h
generated
vendored
@ -1,257 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
|
|
||||||
// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
|
|
||||||
// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_DIYFP_H_
|
|
||||||
#define RAPIDJSON_DIYFP_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
#include "lottie_rapidjson_internal_clzll.h"
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
|
||||||
#include <intrin.h>
|
|
||||||
#pragma intrinsic(_umul128)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct DiyFp {
|
|
||||||
DiyFp() : f(), e() {}
|
|
||||||
|
|
||||||
DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}
|
|
||||||
|
|
||||||
explicit DiyFp(double d) {
|
|
||||||
union {
|
|
||||||
double d;
|
|
||||||
uint64_t u64;
|
|
||||||
} u = { d };
|
|
||||||
|
|
||||||
int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize);
|
|
||||||
uint64_t significand = (u.u64 & kDpSignificandMask);
|
|
||||||
if (biased_e != 0) {
|
|
||||||
f = significand + kDpHiddenBit;
|
|
||||||
e = biased_e - kDpExponentBias;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
f = significand;
|
|
||||||
e = kDpMinExponent + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DiyFp operator-(const DiyFp& rhs) const {
|
|
||||||
return DiyFp(f - rhs.f, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiyFp operator*(const DiyFp& rhs) const {
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
|
||||||
uint64_t h;
|
|
||||||
uint64_t l = _umul128(f, rhs.f, &h);
|
|
||||||
if (l & (uint64_t(1) << 63)) // rounding
|
|
||||||
h++;
|
|
||||||
return DiyFp(h, e + rhs.e + 64);
|
|
||||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
|
||||||
__extension__ typedef unsigned __int128 uint128;
|
|
||||||
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
|
|
||||||
uint64_t h = static_cast<uint64_t>(p >> 64);
|
|
||||||
uint64_t l = static_cast<uint64_t>(p);
|
|
||||||
if (l & (uint64_t(1) << 63)) // rounding
|
|
||||||
h++;
|
|
||||||
return DiyFp(h, e + rhs.e + 64);
|
|
||||||
#else
|
|
||||||
const uint64_t M32 = 0xFFFFFFFF;
|
|
||||||
const uint64_t a = f >> 32;
|
|
||||||
const uint64_t b = f & M32;
|
|
||||||
const uint64_t c = rhs.f >> 32;
|
|
||||||
const uint64_t d = rhs.f & M32;
|
|
||||||
const uint64_t ac = a * c;
|
|
||||||
const uint64_t bc = b * c;
|
|
||||||
const uint64_t ad = a * d;
|
|
||||||
const uint64_t bd = b * d;
|
|
||||||
uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
|
|
||||||
tmp += 1U << 31; /// mult_round
|
|
||||||
return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
DiyFp Normalize() const {
|
|
||||||
int s = static_cast<int>(clzll(f));
|
|
||||||
return DiyFp(f << s, e - s);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiyFp NormalizeBoundary() const {
|
|
||||||
DiyFp res = *this;
|
|
||||||
while (!(res.f & (kDpHiddenBit << 1))) {
|
|
||||||
res.f <<= 1;
|
|
||||||
res.e--;
|
|
||||||
}
|
|
||||||
res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
|
|
||||||
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {
|
|
||||||
DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
|
|
||||||
DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
|
|
||||||
mi.f <<= mi.e - pl.e;
|
|
||||||
mi.e = pl.e;
|
|
||||||
*plus = pl;
|
|
||||||
*minus = mi;
|
|
||||||
}
|
|
||||||
|
|
||||||
double ToDouble() const {
|
|
||||||
union {
|
|
||||||
double d;
|
|
||||||
uint64_t u64;
|
|
||||||
}u;
|
|
||||||
RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask);
|
|
||||||
if (e < kDpDenormalExponent) {
|
|
||||||
// Underflow.
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
if (e >= kDpMaxExponent) {
|
|
||||||
// Overflow.
|
|
||||||
return std::numeric_limits<double>::infinity();
|
|
||||||
}
|
|
||||||
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
|
|
||||||
static_cast<uint64_t>(e + kDpExponentBias);
|
|
||||||
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
|
|
||||||
return u.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int kDiySignificandSize = 64;
|
|
||||||
static const int kDpSignificandSize = 52;
|
|
||||||
static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
|
|
||||||
static const int kDpMaxExponent = 0x7FF - kDpExponentBias;
|
|
||||||
static const int kDpMinExponent = -kDpExponentBias;
|
|
||||||
static const int kDpDenormalExponent = -kDpExponentBias + 1;
|
|
||||||
static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
|
|
||||||
static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
|
|
||||||
static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
|
|
||||||
|
|
||||||
uint64_t f;
|
|
||||||
int e;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline DiyFp GetCachedPowerByIndex(size_t index) {
|
|
||||||
// 10^-348, 10^-340, ..., 10^340
|
|
||||||
static const uint64_t kCachedPowers_F[] = {
|
|
||||||
RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76),
|
|
||||||
RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea),
|
|
||||||
RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df),
|
|
||||||
RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f),
|
|
||||||
RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c),
|
|
||||||
RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5),
|
|
||||||
RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d),
|
|
||||||
RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637),
|
|
||||||
RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7),
|
|
||||||
RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5),
|
|
||||||
RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b),
|
|
||||||
RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996),
|
|
||||||
RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
|
|
||||||
RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8),
|
|
||||||
RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053),
|
|
||||||
RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd),
|
|
||||||
RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94),
|
|
||||||
RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b),
|
|
||||||
RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac),
|
|
||||||
RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3),
|
|
||||||
RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb),
|
|
||||||
RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c),
|
|
||||||
RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000),
|
|
||||||
RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984),
|
|
||||||
RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70),
|
|
||||||
RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245),
|
|
||||||
RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8),
|
|
||||||
RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a),
|
|
||||||
RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea),
|
|
||||||
RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85),
|
|
||||||
RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2),
|
|
||||||
RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3),
|
|
||||||
RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25),
|
|
||||||
RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece),
|
|
||||||
RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5),
|
|
||||||
RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a),
|
|
||||||
RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
|
|
||||||
RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a),
|
|
||||||
RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129),
|
|
||||||
RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429),
|
|
||||||
RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d),
|
|
||||||
RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841),
|
|
||||||
RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9),
|
|
||||||
RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b)
|
|
||||||
};
|
|
||||||
static const int16_t kCachedPowers_E[] = {
|
|
||||||
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
|
|
||||||
-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
|
|
||||||
-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
|
|
||||||
-422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
|
|
||||||
-157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
|
|
||||||
109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
|
|
||||||
375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
|
|
||||||
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
|
|
||||||
907, 933, 960, 986, 1013, 1039, 1066
|
|
||||||
};
|
|
||||||
RAPIDJSON_ASSERT(index < 87);
|
|
||||||
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DiyFp GetCachedPower(int e, int* K) {
|
|
||||||
|
|
||||||
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
|
|
||||||
double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
|
|
||||||
int k = static_cast<int>(dk);
|
|
||||||
if (dk - k > 0.0)
|
|
||||||
k++;
|
|
||||||
|
|
||||||
unsigned index = static_cast<unsigned>((k >> 3) + 1);
|
|
||||||
*K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table
|
|
||||||
|
|
||||||
return GetCachedPowerByIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DiyFp GetCachedPower10(int exp, int *outExp) {
|
|
||||||
RAPIDJSON_ASSERT(exp >= -348);
|
|
||||||
unsigned index = static_cast<unsigned>(exp + 348) / 8u;
|
|
||||||
*outExp = -348 + static_cast<int>(index) * 8;
|
|
||||||
return GetCachedPowerByIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_DIYFP_H_
|
|
245
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_dtoa.h
generated
vendored
245
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_dtoa.h
generated
vendored
@ -1,245 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
|
|
||||||
// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
|
|
||||||
// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_DTOA_
|
|
||||||
#define RAPIDJSON_DTOA_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_internal_itoa.h"
|
|
||||||
#include "lottie_rapidjson_internal_diyfp.h"
|
|
||||||
#include "lottie_rapidjson_internal_ieee754.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
|
|
||||||
while (rest < wp_w && delta - rest >= ten_kappa &&
|
|
||||||
(rest + ten_kappa < wp_w || /// closer
|
|
||||||
wp_w - rest > rest + ten_kappa - wp_w)) {
|
|
||||||
buffer[len - 1]--;
|
|
||||||
rest += ten_kappa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int CountDecimalDigit32(uint32_t n) {
|
|
||||||
// Simple pure C++ implementation was faster than __builtin_clz version in this situation.
|
|
||||||
if (n < 10) return 1;
|
|
||||||
if (n < 100) return 2;
|
|
||||||
if (n < 1000) return 3;
|
|
||||||
if (n < 10000) return 4;
|
|
||||||
if (n < 100000) return 5;
|
|
||||||
if (n < 1000000) return 6;
|
|
||||||
if (n < 10000000) return 7;
|
|
||||||
if (n < 100000000) return 8;
|
|
||||||
// Will not reach 10 digits in DigitGen()
|
|
||||||
//if (n < 1000000000) return 9;
|
|
||||||
//return 10;
|
|
||||||
return 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
|
||||||
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
|
||||||
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
|
||||||
const DiyFp wp_w = Mp - W;
|
|
||||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
|
||||||
uint64_t p2 = Mp.f & (one.f - 1);
|
|
||||||
int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
|
|
||||||
*len = 0;
|
|
||||||
|
|
||||||
while (kappa > 0) {
|
|
||||||
uint32_t d = 0;
|
|
||||||
switch (kappa) {
|
|
||||||
case 9: d = p1 / 100000000; p1 %= 100000000; break;
|
|
||||||
case 8: d = p1 / 10000000; p1 %= 10000000; break;
|
|
||||||
case 7: d = p1 / 1000000; p1 %= 1000000; break;
|
|
||||||
case 6: d = p1 / 100000; p1 %= 100000; break;
|
|
||||||
case 5: d = p1 / 10000; p1 %= 10000; break;
|
|
||||||
case 4: d = p1 / 1000; p1 %= 1000; break;
|
|
||||||
case 3: d = p1 / 100; p1 %= 100; break;
|
|
||||||
case 2: d = p1 / 10; p1 %= 10; break;
|
|
||||||
case 1: d = p1; p1 = 0; break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
if (d || *len)
|
|
||||||
buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
|
|
||||||
kappa--;
|
|
||||||
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
|
|
||||||
if (tmp <= delta) {
|
|
||||||
*K += kappa;
|
|
||||||
GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// kappa = 0
|
|
||||||
for (;;) {
|
|
||||||
p2 *= 10;
|
|
||||||
delta *= 10;
|
|
||||||
char d = static_cast<char>(p2 >> -one.e);
|
|
||||||
if (d || *len)
|
|
||||||
buffer[(*len)++] = static_cast<char>('0' + d);
|
|
||||||
p2 &= one.f - 1;
|
|
||||||
kappa--;
|
|
||||||
if (p2 < delta) {
|
|
||||||
*K += kappa;
|
|
||||||
int index = -kappa;
|
|
||||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Grisu2(double value, char* buffer, int* length, int* K) {
|
|
||||||
const DiyFp v(value);
|
|
||||||
DiyFp w_m, w_p;
|
|
||||||
v.NormalizedBoundaries(&w_m, &w_p);
|
|
||||||
|
|
||||||
const DiyFp c_mk = GetCachedPower(w_p.e, K);
|
|
||||||
const DiyFp W = v.Normalize() * c_mk;
|
|
||||||
DiyFp Wp = w_p * c_mk;
|
|
||||||
DiyFp Wm = w_m * c_mk;
|
|
||||||
Wm.f++;
|
|
||||||
Wp.f--;
|
|
||||||
DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* WriteExponent(int K, char* buffer) {
|
|
||||||
if (K < 0) {
|
|
||||||
*buffer++ = '-';
|
|
||||||
K = -K;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (K >= 100) {
|
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));
|
|
||||||
K %= 100;
|
|
||||||
const char* d = GetDigitsLut() + K * 2;
|
|
||||||
*buffer++ = d[0];
|
|
||||||
*buffer++ = d[1];
|
|
||||||
}
|
|
||||||
else if (K >= 10) {
|
|
||||||
const char* d = GetDigitsLut() + K * 2;
|
|
||||||
*buffer++ = d[0];
|
|
||||||
*buffer++ = d[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(K));
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {
|
|
||||||
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
|
|
||||||
|
|
||||||
if (0 <= k && kk <= 21) {
|
|
||||||
// 1234e7 -> 12340000000
|
|
||||||
for (int i = length; i < kk; i++)
|
|
||||||
buffer[i] = '0';
|
|
||||||
buffer[kk] = '.';
|
|
||||||
buffer[kk + 1] = '0';
|
|
||||||
return &buffer[kk + 2];
|
|
||||||
}
|
|
||||||
else if (0 < kk && kk <= 21) {
|
|
||||||
// 1234e-2 -> 12.34
|
|
||||||
std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
|
|
||||||
buffer[kk] = '.';
|
|
||||||
if (0 > k + maxDecimalPlaces) {
|
|
||||||
// When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1
|
|
||||||
// Remove extra trailing zeros (at least one) after truncation.
|
|
||||||
for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)
|
|
||||||
if (buffer[i] != '0')
|
|
||||||
return &buffer[i + 1];
|
|
||||||
return &buffer[kk + 2]; // Reserve one zero
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return &buffer[length + 1];
|
|
||||||
}
|
|
||||||
else if (-6 < kk && kk <= 0) {
|
|
||||||
// 1234e-6 -> 0.001234
|
|
||||||
const int offset = 2 - kk;
|
|
||||||
std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));
|
|
||||||
buffer[0] = '0';
|
|
||||||
buffer[1] = '.';
|
|
||||||
for (int i = 2; i < offset; i++)
|
|
||||||
buffer[i] = '0';
|
|
||||||
if (length - kk > maxDecimalPlaces) {
|
|
||||||
// When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1
|
|
||||||
// Remove extra trailing zeros (at least one) after truncation.
|
|
||||||
for (int i = maxDecimalPlaces + 1; i > 2; i--)
|
|
||||||
if (buffer[i] != '0')
|
|
||||||
return &buffer[i + 1];
|
|
||||||
return &buffer[3]; // Reserve one zero
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return &buffer[length + offset];
|
|
||||||
}
|
|
||||||
else if (kk < -maxDecimalPlaces) {
|
|
||||||
// Truncate to zero
|
|
||||||
buffer[0] = '0';
|
|
||||||
buffer[1] = '.';
|
|
||||||
buffer[2] = '0';
|
|
||||||
return &buffer[3];
|
|
||||||
}
|
|
||||||
else if (length == 1) {
|
|
||||||
// 1e30
|
|
||||||
buffer[1] = 'e';
|
|
||||||
return WriteExponent(kk - 1, &buffer[2]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// 1234e30 -> 1.234e33
|
|
||||||
std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));
|
|
||||||
buffer[1] = '.';
|
|
||||||
buffer[length + 1] = 'e';
|
|
||||||
return WriteExponent(kk - 1, &buffer[0 + length + 2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {
|
|
||||||
RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);
|
|
||||||
Double d(value);
|
|
||||||
if (d.IsZero()) {
|
|
||||||
if (d.Sign())
|
|
||||||
*buffer++ = '-'; // -0.0, Issue #289
|
|
||||||
buffer[0] = '0';
|
|
||||||
buffer[1] = '.';
|
|
||||||
buffer[2] = '0';
|
|
||||||
return &buffer[3];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (value < 0) {
|
|
||||||
*buffer++ = '-';
|
|
||||||
value = -value;
|
|
||||||
}
|
|
||||||
int length, K;
|
|
||||||
Grisu2(value, buffer, &length, &K);
|
|
||||||
return Prettify(buffer, length, K, maxDecimalPlaces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_DTOA_
|
|
78
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_ieee754.h
generated
vendored
78
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_ieee754.h
generated
vendored
@ -1,78 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_IEEE754_
|
|
||||||
#define RAPIDJSON_IEEE754_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class Double {
|
|
||||||
public:
|
|
||||||
Double() {}
|
|
||||||
Double(double d) : d_(d) {}
|
|
||||||
Double(uint64_t u) : u_(u) {}
|
|
||||||
|
|
||||||
double Value() const { return d_; }
|
|
||||||
uint64_t Uint64Value() const { return u_; }
|
|
||||||
|
|
||||||
double NextPositiveDouble() const {
|
|
||||||
RAPIDJSON_ASSERT(!Sign());
|
|
||||||
return Double(u_ + 1).Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sign() const { return (u_ & kSignMask) != 0; }
|
|
||||||
uint64_t Significand() const { return u_ & kSignificandMask; }
|
|
||||||
int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }
|
|
||||||
|
|
||||||
bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
|
|
||||||
bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
|
|
||||||
bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
|
|
||||||
bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
|
|
||||||
bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
|
|
||||||
|
|
||||||
uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
|
|
||||||
int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
|
|
||||||
uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
|
|
||||||
|
|
||||||
static int EffectiveSignificandSize(int order) {
|
|
||||||
if (order >= -1021)
|
|
||||||
return 53;
|
|
||||||
else if (order <= -1074)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return order + 1074;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const int kSignificandSize = 52;
|
|
||||||
static const int kExponentBias = 0x3FF;
|
|
||||||
static const int kDenormalExponent = 1 - kExponentBias;
|
|
||||||
static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
|
|
||||||
static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
|
|
||||||
static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
|
|
||||||
static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
|
|
||||||
|
|
||||||
union {
|
|
||||||
double d_;
|
|
||||||
uint64_t u_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_IEEE754_
|
|
308
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_itoa.h
generated
vendored
308
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_itoa.h
generated
vendored
@ -1,308 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ITOA_
|
|
||||||
#define RAPIDJSON_ITOA_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
inline const char* GetDigitsLut() {
|
|
||||||
static const char cDigitsLut[200] = {
|
|
||||||
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
|
|
||||||
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
|
|
||||||
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
|
|
||||||
'3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
|
|
||||||
'4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
|
|
||||||
'5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
|
|
||||||
'6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
|
|
||||||
'7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
|
|
||||||
'8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
|
|
||||||
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
|
|
||||||
};
|
|
||||||
return cDigitsLut;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* u32toa(uint32_t value, char* buffer) {
|
|
||||||
RAPIDJSON_ASSERT(buffer != 0);
|
|
||||||
|
|
||||||
const char* cDigitsLut = GetDigitsLut();
|
|
||||||
|
|
||||||
if (value < 10000) {
|
|
||||||
const uint32_t d1 = (value / 100) << 1;
|
|
||||||
const uint32_t d2 = (value % 100) << 1;
|
|
||||||
|
|
||||||
if (value >= 1000)
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
if (value >= 100)
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
if (value >= 10)
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
}
|
|
||||||
else if (value < 100000000) {
|
|
||||||
// value = bbbbcccc
|
|
||||||
const uint32_t b = value / 10000;
|
|
||||||
const uint32_t c = value % 10000;
|
|
||||||
|
|
||||||
const uint32_t d1 = (b / 100) << 1;
|
|
||||||
const uint32_t d2 = (b % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d3 = (c / 100) << 1;
|
|
||||||
const uint32_t d4 = (c % 100) << 1;
|
|
||||||
|
|
||||||
if (value >= 10000000)
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
if (value >= 1000000)
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
if (value >= 100000)
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d4];
|
|
||||||
*buffer++ = cDigitsLut[d4 + 1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// value = aabbbbcccc in decimal
|
|
||||||
|
|
||||||
const uint32_t a = value / 100000000; // 1 to 42
|
|
||||||
value %= 100000000;
|
|
||||||
|
|
||||||
if (a >= 10) {
|
|
||||||
const unsigned i = a << 1;
|
|
||||||
*buffer++ = cDigitsLut[i];
|
|
||||||
*buffer++ = cDigitsLut[i + 1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
|
|
||||||
|
|
||||||
const uint32_t b = value / 10000; // 0 to 9999
|
|
||||||
const uint32_t c = value % 10000; // 0 to 9999
|
|
||||||
|
|
||||||
const uint32_t d1 = (b / 100) << 1;
|
|
||||||
const uint32_t d2 = (b % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d3 = (c / 100) << 1;
|
|
||||||
const uint32_t d4 = (c % 100) << 1;
|
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d4];
|
|
||||||
*buffer++ = cDigitsLut[d4 + 1];
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* i32toa(int32_t value, char* buffer) {
|
|
||||||
RAPIDJSON_ASSERT(buffer != 0);
|
|
||||||
uint32_t u = static_cast<uint32_t>(value);
|
|
||||||
if (value < 0) {
|
|
||||||
*buffer++ = '-';
|
|
||||||
u = ~u + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return u32toa(u, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* u64toa(uint64_t value, char* buffer) {
|
|
||||||
RAPIDJSON_ASSERT(buffer != 0);
|
|
||||||
const char* cDigitsLut = GetDigitsLut();
|
|
||||||
const uint64_t kTen8 = 100000000;
|
|
||||||
const uint64_t kTen9 = kTen8 * 10;
|
|
||||||
const uint64_t kTen10 = kTen8 * 100;
|
|
||||||
const uint64_t kTen11 = kTen8 * 1000;
|
|
||||||
const uint64_t kTen12 = kTen8 * 10000;
|
|
||||||
const uint64_t kTen13 = kTen8 * 100000;
|
|
||||||
const uint64_t kTen14 = kTen8 * 1000000;
|
|
||||||
const uint64_t kTen15 = kTen8 * 10000000;
|
|
||||||
const uint64_t kTen16 = kTen8 * kTen8;
|
|
||||||
|
|
||||||
if (value < kTen8) {
|
|
||||||
uint32_t v = static_cast<uint32_t>(value);
|
|
||||||
if (v < 10000) {
|
|
||||||
const uint32_t d1 = (v / 100) << 1;
|
|
||||||
const uint32_t d2 = (v % 100) << 1;
|
|
||||||
|
|
||||||
if (v >= 1000)
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
if (v >= 100)
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
if (v >= 10)
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// value = bbbbcccc
|
|
||||||
const uint32_t b = v / 10000;
|
|
||||||
const uint32_t c = v % 10000;
|
|
||||||
|
|
||||||
const uint32_t d1 = (b / 100) << 1;
|
|
||||||
const uint32_t d2 = (b % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d3 = (c / 100) << 1;
|
|
||||||
const uint32_t d4 = (c % 100) << 1;
|
|
||||||
|
|
||||||
if (value >= 10000000)
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
if (value >= 1000000)
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
if (value >= 100000)
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d4];
|
|
||||||
*buffer++ = cDigitsLut[d4 + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (value < kTen16) {
|
|
||||||
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
|
|
||||||
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
|
|
||||||
|
|
||||||
const uint32_t b0 = v0 / 10000;
|
|
||||||
const uint32_t c0 = v0 % 10000;
|
|
||||||
|
|
||||||
const uint32_t d1 = (b0 / 100) << 1;
|
|
||||||
const uint32_t d2 = (b0 % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d3 = (c0 / 100) << 1;
|
|
||||||
const uint32_t d4 = (c0 % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t b1 = v1 / 10000;
|
|
||||||
const uint32_t c1 = v1 % 10000;
|
|
||||||
|
|
||||||
const uint32_t d5 = (b1 / 100) << 1;
|
|
||||||
const uint32_t d6 = (b1 % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d7 = (c1 / 100) << 1;
|
|
||||||
const uint32_t d8 = (c1 % 100) << 1;
|
|
||||||
|
|
||||||
if (value >= kTen15)
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
if (value >= kTen14)
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
if (value >= kTen13)
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
if (value >= kTen12)
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
if (value >= kTen11)
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
|
||||||
if (value >= kTen10)
|
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
|
||||||
if (value >= kTen9)
|
|
||||||
*buffer++ = cDigitsLut[d4];
|
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d4 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d5];
|
|
||||||
*buffer++ = cDigitsLut[d5 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d6];
|
|
||||||
*buffer++ = cDigitsLut[d6 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d7];
|
|
||||||
*buffer++ = cDigitsLut[d7 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d8];
|
|
||||||
*buffer++ = cDigitsLut[d8 + 1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
|
|
||||||
value %= kTen16;
|
|
||||||
|
|
||||||
if (a < 10)
|
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
|
|
||||||
else if (a < 100) {
|
|
||||||
const uint32_t i = a << 1;
|
|
||||||
*buffer++ = cDigitsLut[i];
|
|
||||||
*buffer++ = cDigitsLut[i + 1];
|
|
||||||
}
|
|
||||||
else if (a < 1000) {
|
|
||||||
*buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
|
|
||||||
|
|
||||||
const uint32_t i = (a % 100) << 1;
|
|
||||||
*buffer++ = cDigitsLut[i];
|
|
||||||
*buffer++ = cDigitsLut[i + 1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const uint32_t i = (a / 100) << 1;
|
|
||||||
const uint32_t j = (a % 100) << 1;
|
|
||||||
*buffer++ = cDigitsLut[i];
|
|
||||||
*buffer++ = cDigitsLut[i + 1];
|
|
||||||
*buffer++ = cDigitsLut[j];
|
|
||||||
*buffer++ = cDigitsLut[j + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
|
|
||||||
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
|
|
||||||
|
|
||||||
const uint32_t b0 = v0 / 10000;
|
|
||||||
const uint32_t c0 = v0 % 10000;
|
|
||||||
|
|
||||||
const uint32_t d1 = (b0 / 100) << 1;
|
|
||||||
const uint32_t d2 = (b0 % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d3 = (c0 / 100) << 1;
|
|
||||||
const uint32_t d4 = (c0 % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t b1 = v1 / 10000;
|
|
||||||
const uint32_t c1 = v1 % 10000;
|
|
||||||
|
|
||||||
const uint32_t d5 = (b1 / 100) << 1;
|
|
||||||
const uint32_t d6 = (b1 % 100) << 1;
|
|
||||||
|
|
||||||
const uint32_t d7 = (c1 / 100) << 1;
|
|
||||||
const uint32_t d8 = (c1 % 100) << 1;
|
|
||||||
|
|
||||||
*buffer++ = cDigitsLut[d1];
|
|
||||||
*buffer++ = cDigitsLut[d1 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d2];
|
|
||||||
*buffer++ = cDigitsLut[d2 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d3];
|
|
||||||
*buffer++ = cDigitsLut[d3 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d4];
|
|
||||||
*buffer++ = cDigitsLut[d4 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d5];
|
|
||||||
*buffer++ = cDigitsLut[d5 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d6];
|
|
||||||
*buffer++ = cDigitsLut[d6 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d7];
|
|
||||||
*buffer++ = cDigitsLut[d7 + 1];
|
|
||||||
*buffer++ = cDigitsLut[d8];
|
|
||||||
*buffer++ = cDigitsLut[d8 + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* i64toa(int64_t value, char* buffer) {
|
|
||||||
RAPIDJSON_ASSERT(buffer != 0);
|
|
||||||
uint64_t u = static_cast<uint64_t>(value);
|
|
||||||
if (value < 0) {
|
|
||||||
*buffer++ = '-';
|
|
||||||
u = ~u + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return u64toa(u, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_ITOA_
|
|
186
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_meta.h
generated
vendored
186
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_meta.h
generated
vendored
@ -1,186 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_META_H_
|
|
||||||
#define RAPIDJSON_INTERNAL_META_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(6334)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
|
||||||
#include <type_traits>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//@cond RAPIDJSON_INTERNAL
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
|
|
||||||
template <typename T> struct Void { typedef void Type; };
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// BoolType, TrueType, FalseType
|
|
||||||
//
|
|
||||||
template <bool Cond> struct BoolType {
|
|
||||||
static const bool Value = Cond;
|
|
||||||
typedef BoolType Type;
|
|
||||||
};
|
|
||||||
typedef BoolType<true> TrueType;
|
|
||||||
typedef BoolType<false> FalseType;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
|
|
||||||
//
|
|
||||||
|
|
||||||
template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
|
|
||||||
template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
|
|
||||||
template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
|
|
||||||
template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
|
|
||||||
|
|
||||||
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
|
|
||||||
template <> struct AndExprCond<true, true> : TrueType {};
|
|
||||||
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
|
|
||||||
template <> struct OrExprCond<false, false> : FalseType {};
|
|
||||||
|
|
||||||
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
|
|
||||||
template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
|
|
||||||
template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
|
|
||||||
template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// AddConst, MaybeAddConst, RemoveConst
|
|
||||||
template <typename T> struct AddConst { typedef const T Type; };
|
|
||||||
template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
|
|
||||||
template <typename T> struct RemoveConst { typedef T Type; };
|
|
||||||
template <typename T> struct RemoveConst<const T> { typedef T Type; };
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// IsSame, IsConst, IsMoreConst, IsPointer
|
|
||||||
//
|
|
||||||
template <typename T, typename U> struct IsSame : FalseType {};
|
|
||||||
template <typename T> struct IsSame<T, T> : TrueType {};
|
|
||||||
|
|
||||||
template <typename T> struct IsConst : FalseType {};
|
|
||||||
template <typename T> struct IsConst<const T> : TrueType {};
|
|
||||||
|
|
||||||
template <typename CT, typename T>
|
|
||||||
struct IsMoreConst
|
|
||||||
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
|
|
||||||
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
|
|
||||||
|
|
||||||
template <typename T> struct IsPointer : FalseType {};
|
|
||||||
template <typename T> struct IsPointer<T*> : TrueType {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// IsBaseOf
|
|
||||||
//
|
|
||||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
|
||||||
|
|
||||||
template <typename B, typename D> struct IsBaseOf
|
|
||||||
: BoolType< ::std::is_base_of<B,D>::value> {};
|
|
||||||
|
|
||||||
#else // simplified version adopted from Boost
|
|
||||||
|
|
||||||
template<typename B, typename D> struct IsBaseOfImpl {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
|
|
||||||
|
|
||||||
typedef char (&Yes)[1];
|
|
||||||
typedef char (&No) [2];
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static Yes Check(const D*, T);
|
|
||||||
static No Check(const B*, int);
|
|
||||||
|
|
||||||
struct Host {
|
|
||||||
operator const B*() const;
|
|
||||||
operator const D*();
|
|
||||||
};
|
|
||||||
|
|
||||||
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename B, typename D> struct IsBaseOf
|
|
||||||
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// EnableIf / DisableIf
|
|
||||||
//
|
|
||||||
template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
|
|
||||||
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
|
|
||||||
|
|
||||||
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
|
|
||||||
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
|
|
||||||
|
|
||||||
template <typename Condition, typename T = void>
|
|
||||||
struct EnableIf : EnableIfCond<Condition::Value, T> {};
|
|
||||||
|
|
||||||
template <typename Condition, typename T = void>
|
|
||||||
struct DisableIf : DisableIfCond<Condition::Value, T> {};
|
|
||||||
|
|
||||||
// SFINAE helpers
|
|
||||||
struct SfinaeTag {};
|
|
||||||
template <typename T> struct RemoveSfinaeTag;
|
|
||||||
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
|
|
||||||
|
|
||||||
#define RAPIDJSON_REMOVEFPTR_(type) \
|
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
|
|
||||||
< ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
|
|
||||||
|
|
||||||
#define RAPIDJSON_ENABLEIF(cond) \
|
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
|
||||||
|
|
||||||
#define RAPIDJSON_DISABLEIF(cond) \
|
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
|
||||||
|
|
||||||
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond), \
|
|
||||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
|
||||||
|
|
||||||
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond), \
|
|
||||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
//@endcond
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_INTERNAL_META_H_
|
|
55
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_pow10.h
generated
vendored
55
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_pow10.h
generated
vendored
@ -1,55 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_POW10_
|
|
||||||
#define RAPIDJSON_POW10_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
//! Computes integer powers of 10 in double (10.0^n).
|
|
||||||
/*! This function uses lookup table for fast and accurate results.
|
|
||||||
\param n non-negative exponent. Must <= 308.
|
|
||||||
\return 10.0^n
|
|
||||||
*/
|
|
||||||
inline double Pow10(int n) {
|
|
||||||
static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
|
|
||||||
1e+0,
|
|
||||||
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
|
|
||||||
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
|
|
||||||
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
|
|
||||||
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
|
|
||||||
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
|
|
||||||
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
|
|
||||||
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
|
|
||||||
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
|
|
||||||
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
|
|
||||||
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
|
|
||||||
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
|
|
||||||
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
|
|
||||||
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
|
|
||||||
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
|
|
||||||
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
|
|
||||||
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
|
|
||||||
};
|
|
||||||
RAPIDJSON_ASSERT(n >= 0 && n <= 308);
|
|
||||||
return e[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_POW10_
|
|
739
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_regex.h
generated
vendored
739
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_regex.h
generated
vendored
@ -1,739 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_REGEX_H_
|
|
||||||
#define RAPIDJSON_INTERNAL_REGEX_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_allocators.h"
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include "lottie_rapidjson_internal_stack.h"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
|
||||||
#define RAPIDJSON_REGEX_VERBOSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DecodedStream
|
|
||||||
|
|
||||||
template <typename SourceStream, typename Encoding>
|
|
||||||
class DecodedStream {
|
|
||||||
public:
|
|
||||||
DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); }
|
|
||||||
unsigned Peek() { return codepoint_; }
|
|
||||||
unsigned Take() {
|
|
||||||
unsigned c = codepoint_;
|
|
||||||
if (c) // No further decoding when '\0'
|
|
||||||
Decode();
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Decode() {
|
|
||||||
if (!Encoding::Decode(ss_, &codepoint_))
|
|
||||||
codepoint_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceStream& ss_;
|
|
||||||
unsigned codepoint_;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// GenericRegex
|
|
||||||
|
|
||||||
static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1
|
|
||||||
static const SizeType kRegexInvalidRange = ~SizeType(0);
|
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
|
||||||
class GenericRegexSearch;
|
|
||||||
|
|
||||||
//! Regular expression engine with subset of ECMAscript grammar.
|
|
||||||
/*!
|
|
||||||
Supported regular expression syntax:
|
|
||||||
- \c ab Concatenation
|
|
||||||
- \c a|b Alternation
|
|
||||||
- \c a? Zero or one
|
|
||||||
- \c a* Zero or more
|
|
||||||
- \c a+ One or more
|
|
||||||
- \c a{3} Exactly 3 times
|
|
||||||
- \c a{3,} At least 3 times
|
|
||||||
- \c a{3,5} 3 to 5 times
|
|
||||||
- \c (ab) Grouping
|
|
||||||
- \c ^a At the beginning
|
|
||||||
- \c a$ At the end
|
|
||||||
- \c . Any character
|
|
||||||
- \c [abc] Character classes
|
|
||||||
- \c [a-c] Character class range
|
|
||||||
- \c [a-z0-9_] Character class combination
|
|
||||||
- \c [^abc] Negated character classes
|
|
||||||
- \c [^a-c] Negated character class range
|
|
||||||
- \c [\b] Backspace (U+0008)
|
|
||||||
- \c \\| \\\\ ... Escape characters
|
|
||||||
- \c \\f Form feed (U+000C)
|
|
||||||
- \c \\n Line feed (U+000A)
|
|
||||||
- \c \\r Carriage return (U+000D)
|
|
||||||
- \c \\t Tab (U+0009)
|
|
||||||
- \c \\v Vertical tab (U+000B)
|
|
||||||
|
|
||||||
\note This is a Thompson NFA engine, implemented with reference to
|
|
||||||
Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).",
|
|
||||||
https://swtch.com/~rsc/regexp/regexp1.html
|
|
||||||
*/
|
|
||||||
template <typename Encoding, typename Allocator = CrtAllocator>
|
|
||||||
class GenericRegex {
|
|
||||||
public:
|
|
||||||
typedef Encoding EncodingType;
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
template <typename, typename> friend class GenericRegexSearch;
|
|
||||||
|
|
||||||
GenericRegex(const Ch* source, Allocator* allocator = 0) :
|
|
||||||
ownAllocator_(allocator ? 0 : RAPIDJSON_NEW(Allocator)()), allocator_(allocator ? allocator : ownAllocator_),
|
|
||||||
states_(allocator_, 256), ranges_(allocator_, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
|
|
||||||
anchorBegin_(), anchorEnd_()
|
|
||||||
{
|
|
||||||
GenericStringStream<Encoding> ss(source);
|
|
||||||
DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);
|
|
||||||
Parse(ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
~GenericRegex()
|
|
||||||
{
|
|
||||||
RAPIDJSON_DELETE(ownAllocator_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsValid() const {
|
|
||||||
return root_ != kRegexInvalidState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum Operator {
|
|
||||||
kZeroOrOne,
|
|
||||||
kZeroOrMore,
|
|
||||||
kOneOrMore,
|
|
||||||
kConcatenation,
|
|
||||||
kAlternation,
|
|
||||||
kLeftParenthesis
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.'
|
|
||||||
static const unsigned kRangeCharacterClass = 0xFFFFFFFE;
|
|
||||||
static const unsigned kRangeNegationFlag = 0x80000000;
|
|
||||||
|
|
||||||
struct Range {
|
|
||||||
unsigned start; //
|
|
||||||
unsigned end;
|
|
||||||
SizeType next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct State {
|
|
||||||
SizeType out; //!< Equals to kInvalid for matching state
|
|
||||||
SizeType out1; //!< Equals to non-kInvalid for split
|
|
||||||
SizeType rangeStart;
|
|
||||||
unsigned codepoint;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Frag {
|
|
||||||
Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {}
|
|
||||||
SizeType start;
|
|
||||||
SizeType out; //!< link-list of all output states
|
|
||||||
SizeType minIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
State& GetState(SizeType index) {
|
|
||||||
RAPIDJSON_ASSERT(index < stateCount_);
|
|
||||||
return states_.template Bottom<State>()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const State& GetState(SizeType index) const {
|
|
||||||
RAPIDJSON_ASSERT(index < stateCount_);
|
|
||||||
return states_.template Bottom<State>()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
Range& GetRange(SizeType index) {
|
|
||||||
RAPIDJSON_ASSERT(index < rangeCount_);
|
|
||||||
return ranges_.template Bottom<Range>()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const Range& GetRange(SizeType index) const {
|
|
||||||
RAPIDJSON_ASSERT(index < rangeCount_);
|
|
||||||
return ranges_.template Bottom<Range>()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
void Parse(DecodedStream<InputStream, Encoding>& ds) {
|
|
||||||
Stack<Allocator> operandStack(allocator_, 256); // Frag
|
|
||||||
Stack<Allocator> operatorStack(allocator_, 256); // Operator
|
|
||||||
Stack<Allocator> atomCountStack(allocator_, 256); // unsigned (Atom per parenthesis)
|
|
||||||
|
|
||||||
*atomCountStack.template Push<unsigned>() = 0;
|
|
||||||
|
|
||||||
unsigned codepoint;
|
|
||||||
while (ds.Peek() != 0) {
|
|
||||||
switch (codepoint = ds.Take()) {
|
|
||||||
case '^':
|
|
||||||
anchorBegin_ = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '$':
|
|
||||||
anchorEnd_ = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '|':
|
|
||||||
while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() < kAlternation)
|
|
||||||
if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
|
|
||||||
return;
|
|
||||||
*operatorStack.template Push<Operator>() = kAlternation;
|
|
||||||
*atomCountStack.template Top<unsigned>() = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '(':
|
|
||||||
*operatorStack.template Push<Operator>() = kLeftParenthesis;
|
|
||||||
*atomCountStack.template Push<unsigned>() = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ')':
|
|
||||||
while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() != kLeftParenthesis)
|
|
||||||
if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
|
|
||||||
return;
|
|
||||||
if (operatorStack.Empty())
|
|
||||||
return;
|
|
||||||
operatorStack.template Pop<Operator>(1);
|
|
||||||
atomCountStack.template Pop<unsigned>(1);
|
|
||||||
ImplicitConcatenation(atomCountStack, operatorStack);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
if (!Eval(operandStack, kZeroOrOne))
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '*':
|
|
||||||
if (!Eval(operandStack, kZeroOrMore))
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '+':
|
|
||||||
if (!Eval(operandStack, kOneOrMore))
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '{':
|
|
||||||
{
|
|
||||||
unsigned n, m;
|
|
||||||
if (!ParseUnsigned(ds, &n))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ds.Peek() == ',') {
|
|
||||||
ds.Take();
|
|
||||||
if (ds.Peek() == '}')
|
|
||||||
m = kInfinityQuantifier;
|
|
||||||
else if (!ParseUnsigned(ds, &m) || m < n)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m = n;
|
|
||||||
|
|
||||||
if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')
|
|
||||||
return;
|
|
||||||
ds.Take();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '.':
|
|
||||||
PushOperand(operandStack, kAnyCharacterClass);
|
|
||||||
ImplicitConcatenation(atomCountStack, operatorStack);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '[':
|
|
||||||
{
|
|
||||||
SizeType range;
|
|
||||||
if (!ParseRange(ds, &range))
|
|
||||||
return;
|
|
||||||
SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass);
|
|
||||||
GetState(s).rangeStart = range;
|
|
||||||
*operandStack.template Push<Frag>() = Frag(s, s, s);
|
|
||||||
}
|
|
||||||
ImplicitConcatenation(atomCountStack, operatorStack);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\\': // Escape character
|
|
||||||
if (!CharacterEscape(ds, &codepoint))
|
|
||||||
return; // Unsupported escape character
|
|
||||||
// fall through to default
|
|
||||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
|
||||||
|
|
||||||
default: // Pattern character
|
|
||||||
PushOperand(operandStack, codepoint);
|
|
||||||
ImplicitConcatenation(atomCountStack, operatorStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!operatorStack.Empty())
|
|
||||||
if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Link the operand to matching state.
|
|
||||||
if (operandStack.GetSize() == sizeof(Frag)) {
|
|
||||||
Frag* e = operandStack.template Pop<Frag>(1);
|
|
||||||
Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0));
|
|
||||||
root_ = e->start;
|
|
||||||
|
|
||||||
#if RAPIDJSON_REGEX_VERBOSE
|
|
||||||
printf("root: %d\n", root_);
|
|
||||||
for (SizeType i = 0; i < stateCount_ ; i++) {
|
|
||||||
State& s = GetState(i);
|
|
||||||
printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) {
|
|
||||||
State* s = states_.template Push<State>();
|
|
||||||
s->out = out;
|
|
||||||
s->out1 = out1;
|
|
||||||
s->codepoint = codepoint;
|
|
||||||
s->rangeStart = kRegexInvalidRange;
|
|
||||||
return stateCount_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushOperand(Stack<Allocator>& operandStack, unsigned codepoint) {
|
|
||||||
SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint);
|
|
||||||
*operandStack.template Push<Frag>() = Frag(s, s, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImplicitConcatenation(Stack<Allocator>& atomCountStack, Stack<Allocator>& operatorStack) {
|
|
||||||
if (*atomCountStack.template Top<unsigned>())
|
|
||||||
*operatorStack.template Push<Operator>() = kConcatenation;
|
|
||||||
(*atomCountStack.template Top<unsigned>())++;
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType Append(SizeType l1, SizeType l2) {
|
|
||||||
SizeType old = l1;
|
|
||||||
while (GetState(l1).out != kRegexInvalidState)
|
|
||||||
l1 = GetState(l1).out;
|
|
||||||
GetState(l1).out = l2;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Patch(SizeType l, SizeType s) {
|
|
||||||
for (SizeType next; l != kRegexInvalidState; l = next) {
|
|
||||||
next = GetState(l).out;
|
|
||||||
GetState(l).out = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Eval(Stack<Allocator>& operandStack, Operator op) {
|
|
||||||
switch (op) {
|
|
||||||
case kConcatenation:
|
|
||||||
RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2);
|
|
||||||
{
|
|
||||||
Frag e2 = *operandStack.template Pop<Frag>(1);
|
|
||||||
Frag e1 = *operandStack.template Pop<Frag>(1);
|
|
||||||
Patch(e1.out, e2.start);
|
|
||||||
*operandStack.template Push<Frag>() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case kAlternation:
|
|
||||||
if (operandStack.GetSize() >= sizeof(Frag) * 2) {
|
|
||||||
Frag e2 = *operandStack.template Pop<Frag>(1);
|
|
||||||
Frag e1 = *operandStack.template Pop<Frag>(1);
|
|
||||||
SizeType s = NewState(e1.start, e2.start, 0);
|
|
||||||
*operandStack.template Push<Frag>() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case kZeroOrOne:
|
|
||||||
if (operandStack.GetSize() >= sizeof(Frag)) {
|
|
||||||
Frag e = *operandStack.template Pop<Frag>(1);
|
|
||||||
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
|
||||||
*operandStack.template Push<Frag>() = Frag(s, Append(e.out, s), e.minIndex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case kZeroOrMore:
|
|
||||||
if (operandStack.GetSize() >= sizeof(Frag)) {
|
|
||||||
Frag e = *operandStack.template Pop<Frag>(1);
|
|
||||||
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
|
||||||
Patch(e.out, s);
|
|
||||||
*operandStack.template Push<Frag>() = Frag(s, s, e.minIndex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case kOneOrMore:
|
|
||||||
if (operandStack.GetSize() >= sizeof(Frag)) {
|
|
||||||
Frag e = *operandStack.template Pop<Frag>(1);
|
|
||||||
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
|
||||||
Patch(e.out, s);
|
|
||||||
*operandStack.template Push<Frag>() = Frag(e.start, s, e.minIndex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// syntax error (e.g. unclosed kLeftParenthesis)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EvalQuantifier(Stack<Allocator>& operandStack, unsigned n, unsigned m) {
|
|
||||||
RAPIDJSON_ASSERT(n <= m);
|
|
||||||
RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag));
|
|
||||||
|
|
||||||
if (n == 0) {
|
|
||||||
if (m == 0) // a{0} not support
|
|
||||||
return false;
|
|
||||||
else if (m == kInfinityQuantifier)
|
|
||||||
Eval(operandStack, kZeroOrMore); // a{0,} -> a*
|
|
||||||
else {
|
|
||||||
Eval(operandStack, kZeroOrOne); // a{0,5} -> a?
|
|
||||||
for (unsigned i = 0; i < m - 1; i++)
|
|
||||||
CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a?
|
|
||||||
for (unsigned i = 0; i < m - 1; i++)
|
|
||||||
Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a?
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a
|
|
||||||
CloneTopOperand(operandStack);
|
|
||||||
|
|
||||||
if (m == kInfinityQuantifier)
|
|
||||||
Eval(operandStack, kOneOrMore); // a{3,} -> a a a+
|
|
||||||
else if (m > n) {
|
|
||||||
CloneTopOperand(operandStack); // a{3,5} -> a a a a
|
|
||||||
Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a?
|
|
||||||
for (unsigned i = n; i < m - 1; i++)
|
|
||||||
CloneTopOperand(operandStack); // a{3,5} -> a a a a? a?
|
|
||||||
for (unsigned i = n; i < m; i++)
|
|
||||||
Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a?
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < n - 1; i++)
|
|
||||||
Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a?
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; }
|
|
||||||
|
|
||||||
void CloneTopOperand(Stack<Allocator>& operandStack) {
|
|
||||||
const Frag src = *operandStack.template Top<Frag>(); // Copy constructor to prevent invalidation
|
|
||||||
SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_)
|
|
||||||
State* s = states_.template Push<State>(count);
|
|
||||||
memcpy(s, &GetState(src.minIndex), count * sizeof(State));
|
|
||||||
for (SizeType j = 0; j < count; j++) {
|
|
||||||
if (s[j].out != kRegexInvalidState)
|
|
||||||
s[j].out += count;
|
|
||||||
if (s[j].out1 != kRegexInvalidState)
|
|
||||||
s[j].out1 += count;
|
|
||||||
}
|
|
||||||
*operandStack.template Push<Frag>() = Frag(src.start + count, src.out + count, src.minIndex + count);
|
|
||||||
stateCount_ += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
bool ParseUnsigned(DecodedStream<InputStream, Encoding>& ds, unsigned* u) {
|
|
||||||
unsigned r = 0;
|
|
||||||
if (ds.Peek() < '0' || ds.Peek() > '9')
|
|
||||||
return false;
|
|
||||||
while (ds.Peek() >= '0' && ds.Peek() <= '9') {
|
|
||||||
if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295
|
|
||||||
return false; // overflow
|
|
||||||
r = r * 10 + (ds.Take() - '0');
|
|
||||||
}
|
|
||||||
*u = r;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
bool ParseRange(DecodedStream<InputStream, Encoding>& ds, SizeType* range) {
|
|
||||||
bool isBegin = true;
|
|
||||||
bool negate = false;
|
|
||||||
int step = 0;
|
|
||||||
SizeType start = kRegexInvalidRange;
|
|
||||||
SizeType current = kRegexInvalidRange;
|
|
||||||
unsigned codepoint;
|
|
||||||
while ((codepoint = ds.Take()) != 0) {
|
|
||||||
if (isBegin) {
|
|
||||||
isBegin = false;
|
|
||||||
if (codepoint == '^') {
|
|
||||||
negate = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (codepoint) {
|
|
||||||
case ']':
|
|
||||||
if (start == kRegexInvalidRange)
|
|
||||||
return false; // Error: nothing inside []
|
|
||||||
if (step == 2) { // Add trailing '-'
|
|
||||||
SizeType r = NewRange('-');
|
|
||||||
RAPIDJSON_ASSERT(current != kRegexInvalidRange);
|
|
||||||
GetRange(current).next = r;
|
|
||||||
}
|
|
||||||
if (negate)
|
|
||||||
GetRange(start).start |= kRangeNegationFlag;
|
|
||||||
*range = start;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
if (ds.Peek() == 'b') {
|
|
||||||
ds.Take();
|
|
||||||
codepoint = 0x0008; // Escape backspace character
|
|
||||||
}
|
|
||||||
else if (!CharacterEscape(ds, &codepoint))
|
|
||||||
return false;
|
|
||||||
// fall through to default
|
|
||||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
|
||||||
|
|
||||||
default:
|
|
||||||
switch (step) {
|
|
||||||
case 1:
|
|
||||||
if (codepoint == '-') {
|
|
||||||
step++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fall through to step 0 for other characters
|
|
||||||
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
SizeType r = NewRange(codepoint);
|
|
||||||
if (current != kRegexInvalidRange)
|
|
||||||
GetRange(current).next = r;
|
|
||||||
if (start == kRegexInvalidRange)
|
|
||||||
start = r;
|
|
||||||
current = r;
|
|
||||||
}
|
|
||||||
step = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
RAPIDJSON_ASSERT(step == 2);
|
|
||||||
GetRange(current).end = codepoint;
|
|
||||||
step = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeType NewRange(unsigned codepoint) {
|
|
||||||
Range* r = ranges_.template Push<Range>();
|
|
||||||
r->start = r->end = codepoint;
|
|
||||||
r->next = kRegexInvalidRange;
|
|
||||||
return rangeCount_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
bool CharacterEscape(DecodedStream<InputStream, Encoding>& ds, unsigned* escapedCodepoint) {
|
|
||||||
unsigned codepoint;
|
|
||||||
switch (codepoint = ds.Take()) {
|
|
||||||
case '^':
|
|
||||||
case '$':
|
|
||||||
case '|':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '?':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case '.':
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case '{':
|
|
||||||
case '}':
|
|
||||||
case '\\':
|
|
||||||
*escapedCodepoint = codepoint; return true;
|
|
||||||
case 'f': *escapedCodepoint = 0x000C; return true;
|
|
||||||
case 'n': *escapedCodepoint = 0x000A; return true;
|
|
||||||
case 'r': *escapedCodepoint = 0x000D; return true;
|
|
||||||
case 't': *escapedCodepoint = 0x0009; return true;
|
|
||||||
case 'v': *escapedCodepoint = 0x000B; return true;
|
|
||||||
default:
|
|
||||||
return false; // Unsupported escape character
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Allocator* ownAllocator_;
|
|
||||||
Allocator* allocator_;
|
|
||||||
Stack<Allocator> states_;
|
|
||||||
Stack<Allocator> ranges_;
|
|
||||||
SizeType root_;
|
|
||||||
SizeType stateCount_;
|
|
||||||
SizeType rangeCount_;
|
|
||||||
|
|
||||||
static const unsigned kInfinityQuantifier = ~0u;
|
|
||||||
|
|
||||||
// For SearchWithAnchoring()
|
|
||||||
bool anchorBegin_;
|
|
||||||
bool anchorEnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename RegexType, typename Allocator = CrtAllocator>
|
|
||||||
class GenericRegexSearch {
|
|
||||||
public:
|
|
||||||
typedef typename RegexType::EncodingType Encoding;
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) :
|
|
||||||
regex_(regex), allocator_(allocator), ownAllocator_(0),
|
|
||||||
state0_(allocator, 0), state1_(allocator, 0), stateSet_()
|
|
||||||
{
|
|
||||||
RAPIDJSON_ASSERT(regex_.IsValid());
|
|
||||||
if (!allocator_)
|
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
|
||||||
stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));
|
|
||||||
state0_.template Reserve<SizeType>(regex_.stateCount_);
|
|
||||||
state1_.template Reserve<SizeType>(regex_.stateCount_);
|
|
||||||
}
|
|
||||||
|
|
||||||
~GenericRegexSearch() {
|
|
||||||
Allocator::Free(stateSet_);
|
|
||||||
RAPIDJSON_DELETE(ownAllocator_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
bool Match(InputStream& is) {
|
|
||||||
return SearchWithAnchoring(is, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Match(const Ch* s) {
|
|
||||||
GenericStringStream<Encoding> is(s);
|
|
||||||
return Match(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
bool Search(InputStream& is) {
|
|
||||||
return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Search(const Ch* s) {
|
|
||||||
GenericStringStream<Encoding> is(s);
|
|
||||||
return Search(is);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef typename RegexType::State State;
|
|
||||||
typedef typename RegexType::Range Range;
|
|
||||||
|
|
||||||
template <typename InputStream>
|
|
||||||
bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) {
|
|
||||||
DecodedStream<InputStream, Encoding> ds(is);
|
|
||||||
|
|
||||||
state0_.Clear();
|
|
||||||
Stack<Allocator> *current = &state0_, *next = &state1_;
|
|
||||||
const size_t stateSetSize = GetStateSetSize();
|
|
||||||
std::memset(stateSet_, 0, stateSetSize);
|
|
||||||
|
|
||||||
bool matched = AddState(*current, regex_.root_);
|
|
||||||
unsigned codepoint;
|
|
||||||
while (!current->Empty() && (codepoint = ds.Take()) != 0) {
|
|
||||||
std::memset(stateSet_, 0, stateSetSize);
|
|
||||||
next->Clear();
|
|
||||||
matched = false;
|
|
||||||
for (const SizeType* s = current->template Bottom<SizeType>(); s != current->template End<SizeType>(); ++s) {
|
|
||||||
const State& sr = regex_.GetState(*s);
|
|
||||||
if (sr.codepoint == codepoint ||
|
|
||||||
sr.codepoint == RegexType::kAnyCharacterClass ||
|
|
||||||
(sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint)))
|
|
||||||
{
|
|
||||||
matched = AddState(*next, sr.out) || matched;
|
|
||||||
if (!anchorEnd && matched)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!anchorBegin)
|
|
||||||
AddState(*next, regex_.root_);
|
|
||||||
}
|
|
||||||
internal::Swap(current, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
return matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetStateSetSize() const {
|
|
||||||
return (regex_.stateCount_ + 31) / 32 * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return whether the added states is a match state
|
|
||||||
bool AddState(Stack<Allocator>& l, SizeType index) {
|
|
||||||
RAPIDJSON_ASSERT(index != kRegexInvalidState);
|
|
||||||
|
|
||||||
const State& s = regex_.GetState(index);
|
|
||||||
if (s.out1 != kRegexInvalidState) { // Split
|
|
||||||
bool matched = AddState(l, s.out);
|
|
||||||
return AddState(l, s.out1) || matched;
|
|
||||||
}
|
|
||||||
else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) {
|
|
||||||
stateSet_[index >> 5] |= (1u << (index & 31));
|
|
||||||
*l.template PushUnsafe<SizeType>() = index;
|
|
||||||
}
|
|
||||||
return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation.
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MatchRange(SizeType rangeIndex, unsigned codepoint) const {
|
|
||||||
bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0;
|
|
||||||
while (rangeIndex != kRegexInvalidRange) {
|
|
||||||
const Range& r = regex_.GetRange(rangeIndex);
|
|
||||||
if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end)
|
|
||||||
return yes;
|
|
||||||
rangeIndex = r.next;
|
|
||||||
}
|
|
||||||
return !yes;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RegexType& regex_;
|
|
||||||
Allocator* allocator_;
|
|
||||||
Allocator* ownAllocator_;
|
|
||||||
Stack<Allocator> state0_;
|
|
||||||
Stack<Allocator> state1_;
|
|
||||||
uint32_t* stateSet_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef GenericRegex<UTF8<> > Regex;
|
|
||||||
typedef GenericRegexSearch<Regex> RegexSearch;
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__) || defined(_MSC_VER)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_INTERNAL_REGEX_H_
|
|
232
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_stack.h
generated
vendored
232
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_stack.h
generated
vendored
@ -1,232 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_STACK_H_
|
|
||||||
#define RAPIDJSON_INTERNAL_STACK_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_allocators.h"
|
|
||||||
#include "lottie_rapidjson_internal_swap.h"
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Stack
|
|
||||||
|
|
||||||
//! A type-unsafe stack for storing different types of data.
|
|
||||||
/*! \tparam Allocator Allocator for allocating stack memory.
|
|
||||||
*/
|
|
||||||
template <typename Allocator>
|
|
||||||
class Stack {
|
|
||||||
public:
|
|
||||||
// Optimization note: Do not allocate memory for stack_ in constructor.
|
|
||||||
// Do it lazily when first Push() -> Expand() -> Resize().
|
|
||||||
Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
Stack(Stack&& rhs)
|
|
||||||
: allocator_(rhs.allocator_),
|
|
||||||
ownAllocator_(rhs.ownAllocator_),
|
|
||||||
stack_(rhs.stack_),
|
|
||||||
stackTop_(rhs.stackTop_),
|
|
||||||
stackEnd_(rhs.stackEnd_),
|
|
||||||
initialCapacity_(rhs.initialCapacity_)
|
|
||||||
{
|
|
||||||
rhs.allocator_ = 0;
|
|
||||||
rhs.ownAllocator_ = 0;
|
|
||||||
rhs.stack_ = 0;
|
|
||||||
rhs.stackTop_ = 0;
|
|
||||||
rhs.stackEnd_ = 0;
|
|
||||||
rhs.initialCapacity_ = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
~Stack() {
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
Stack& operator=(Stack&& rhs) {
|
|
||||||
if (&rhs != this)
|
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
|
|
||||||
allocator_ = rhs.allocator_;
|
|
||||||
ownAllocator_ = rhs.ownAllocator_;
|
|
||||||
stack_ = rhs.stack_;
|
|
||||||
stackTop_ = rhs.stackTop_;
|
|
||||||
stackEnd_ = rhs.stackEnd_;
|
|
||||||
initialCapacity_ = rhs.initialCapacity_;
|
|
||||||
|
|
||||||
rhs.allocator_ = 0;
|
|
||||||
rhs.ownAllocator_ = 0;
|
|
||||||
rhs.stack_ = 0;
|
|
||||||
rhs.stackTop_ = 0;
|
|
||||||
rhs.stackEnd_ = 0;
|
|
||||||
rhs.initialCapacity_ = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
|
|
||||||
internal::Swap(allocator_, rhs.allocator_);
|
|
||||||
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
|
||||||
internal::Swap(stack_, rhs.stack_);
|
|
||||||
internal::Swap(stackTop_, rhs.stackTop_);
|
|
||||||
internal::Swap(stackEnd_, rhs.stackEnd_);
|
|
||||||
internal::Swap(initialCapacity_, rhs.initialCapacity_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() { stackTop_ = stack_; }
|
|
||||||
|
|
||||||
void ShrinkToFit() {
|
|
||||||
if (Empty()) {
|
|
||||||
// If the stack is empty, completely deallocate the memory.
|
|
||||||
Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
|
|
||||||
stack_ = 0;
|
|
||||||
stackTop_ = 0;
|
|
||||||
stackEnd_ = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Resize(GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimization note: try to minimize the size of this function for force inline.
|
|
||||||
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
|
|
||||||
template<typename T>
|
|
||||||
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
|
||||||
// Expand the stack if needed
|
|
||||||
if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
|
|
||||||
Expand<T>(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
|
|
||||||
Reserve<T>(count);
|
|
||||||
return PushUnsafe<T>(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
|
||||||
RAPIDJSON_ASSERT(stackTop_);
|
|
||||||
RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
|
|
||||||
T* ret = reinterpret_cast<T*>(stackTop_);
|
|
||||||
stackTop_ += sizeof(T) * count;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T* Pop(size_t count) {
|
|
||||||
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
|
|
||||||
stackTop_ -= count * sizeof(T);
|
|
||||||
return reinterpret_cast<T*>(stackTop_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T* Top() {
|
|
||||||
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
|
||||||
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T* Top() const {
|
|
||||||
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
|
||||||
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T* End() { return reinterpret_cast<T*>(stackTop_); }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T* End() const { return reinterpret_cast<T*>(stackTop_); }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T* Bottom() { return reinterpret_cast<T*>(stack_); }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T* Bottom() const { return reinterpret_cast<T*>(stack_); }
|
|
||||||
|
|
||||||
bool HasAllocator() const {
|
|
||||||
return allocator_ != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Allocator& GetAllocator() {
|
|
||||||
RAPIDJSON_ASSERT(allocator_);
|
|
||||||
return *allocator_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Empty() const { return stackTop_ == stack_; }
|
|
||||||
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
|
|
||||||
size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename T>
|
|
||||||
void Expand(size_t count) {
|
|
||||||
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
|
|
||||||
size_t newCapacity;
|
|
||||||
if (stack_ == 0) {
|
|
||||||
if (!allocator_)
|
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
|
||||||
newCapacity = initialCapacity_;
|
|
||||||
} else {
|
|
||||||
newCapacity = GetCapacity();
|
|
||||||
newCapacity += (newCapacity + 1) / 2;
|
|
||||||
}
|
|
||||||
size_t newSize = GetSize() + sizeof(T) * count;
|
|
||||||
if (newCapacity < newSize)
|
|
||||||
newCapacity = newSize;
|
|
||||||
|
|
||||||
Resize(newCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resize(size_t newCapacity) {
|
|
||||||
const size_t size = GetSize(); // Backup the current size
|
|
||||||
stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
|
|
||||||
stackTop_ = stack_ + size;
|
|
||||||
stackEnd_ = stack_ + newCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Destroy() {
|
|
||||||
Allocator::Free(stack_);
|
|
||||||
RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
|
||||||
Stack(const Stack&);
|
|
||||||
Stack& operator=(const Stack&);
|
|
||||||
|
|
||||||
Allocator* allocator_;
|
|
||||||
Allocator* ownAllocator_;
|
|
||||||
char *stack_;
|
|
||||||
char *stackTop_;
|
|
||||||
char *stackEnd_;
|
|
||||||
size_t initialCapacity_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_STACK_H_
|
|
69
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_strfunc.h
generated
vendored
69
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_strfunc.h
generated
vendored
@ -1,69 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
|
|
||||||
#define RAPIDJSON_INTERNAL_STRFUNC_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include <cwchar>
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
//! Custom strlen() which works on different character types.
|
|
||||||
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
|
|
||||||
\param s Null-terminated input string.
|
|
||||||
\return Number of characters in the string.
|
|
||||||
\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
|
|
||||||
*/
|
|
||||||
template <typename Ch>
|
|
||||||
inline SizeType StrLen(const Ch* s) {
|
|
||||||
RAPIDJSON_ASSERT(s != 0);
|
|
||||||
const Ch* p = s;
|
|
||||||
while (*p) ++p;
|
|
||||||
return SizeType(p - s);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline SizeType StrLen(const char* s) {
|
|
||||||
return SizeType(std::strlen(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline SizeType StrLen(const wchar_t* s) {
|
|
||||||
return SizeType(std::wcslen(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns number of code points in a encoded string.
|
|
||||||
template<typename Encoding>
|
|
||||||
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
|
|
||||||
RAPIDJSON_ASSERT(s != 0);
|
|
||||||
RAPIDJSON_ASSERT(outCount != 0);
|
|
||||||
GenericStringStream<Encoding> is(s);
|
|
||||||
const typename Encoding::Ch* end = s + length;
|
|
||||||
SizeType count = 0;
|
|
||||||
while (is.src_ < end) {
|
|
||||||
unsigned codepoint;
|
|
||||||
if (!Encoding::Decode(is, &codepoint))
|
|
||||||
return false;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
*outCount = count;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
|
|
290
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_strtod.h
generated
vendored
290
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_strtod.h
generated
vendored
@ -1,290 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_STRTOD_
|
|
||||||
#define RAPIDJSON_STRTOD_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_internal_ieee754.h"
|
|
||||||
#include "lottie_rapidjson_internal_biginteger.h"
|
|
||||||
#include "lottie_rapidjson_internal_diyfp.h"
|
|
||||||
#include "lottie_rapidjson_internal_pow10.h"
|
|
||||||
#include <climits>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
inline double FastPath(double significand, int exp) {
|
|
||||||
if (exp < -308)
|
|
||||||
return 0.0;
|
|
||||||
else if (exp >= 0)
|
|
||||||
return significand * internal::Pow10(exp);
|
|
||||||
else
|
|
||||||
return significand / internal::Pow10(-exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double StrtodNormalPrecision(double d, int p) {
|
|
||||||
if (p < -308) {
|
|
||||||
// Prevent expSum < -308, making Pow10(p) = 0
|
|
||||||
d = FastPath(d, -308);
|
|
||||||
d = FastPath(d, p + 308);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d = FastPath(d, p);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T Min3(T a, T b, T c) {
|
|
||||||
T m = a;
|
|
||||||
if (m > b) m = b;
|
|
||||||
if (m > c) m = c;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
|
|
||||||
const Double db(b);
|
|
||||||
const uint64_t bInt = db.IntegerSignificand();
|
|
||||||
const int bExp = db.IntegerExponent();
|
|
||||||
const int hExp = bExp - 1;
|
|
||||||
|
|
||||||
int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0;
|
|
||||||
|
|
||||||
// Adjust for decimal exponent
|
|
||||||
if (dExp >= 0) {
|
|
||||||
dS_Exp2 += dExp;
|
|
||||||
dS_Exp5 += dExp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bS_Exp2 -= dExp;
|
|
||||||
bS_Exp5 -= dExp;
|
|
||||||
hS_Exp2 -= dExp;
|
|
||||||
hS_Exp5 -= dExp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust for binary exponent
|
|
||||||
if (bExp >= 0)
|
|
||||||
bS_Exp2 += bExp;
|
|
||||||
else {
|
|
||||||
dS_Exp2 -= bExp;
|
|
||||||
hS_Exp2 -= bExp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust for half ulp exponent
|
|
||||||
if (hExp >= 0)
|
|
||||||
hS_Exp2 += hExp;
|
|
||||||
else {
|
|
||||||
dS_Exp2 -= hExp;
|
|
||||||
bS_Exp2 -= hExp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove common power of two factor from all three scaled values
|
|
||||||
int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2);
|
|
||||||
dS_Exp2 -= common_Exp2;
|
|
||||||
bS_Exp2 -= common_Exp2;
|
|
||||||
hS_Exp2 -= common_Exp2;
|
|
||||||
|
|
||||||
BigInteger dS = d;
|
|
||||||
dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);
|
|
||||||
|
|
||||||
BigInteger bS(bInt);
|
|
||||||
bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);
|
|
||||||
|
|
||||||
BigInteger hS(1);
|
|
||||||
hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);
|
|
||||||
|
|
||||||
BigInteger delta(0);
|
|
||||||
dS.Difference(bS, &delta);
|
|
||||||
|
|
||||||
return delta.Compare(hS);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool StrtodFast(double d, int p, double* result) {
|
|
||||||
// Use fast path for string-to-double conversion if possible
|
|
||||||
// see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
|
|
||||||
if (p > 22 && p < 22 + 16) {
|
|
||||||
// Fast Path Cases In Disguise
|
|
||||||
d *= internal::Pow10(p - 22);
|
|
||||||
p = 22;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1
|
|
||||||
*result = FastPath(d, p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute an approximation and see if it is within 1/2 ULP
|
|
||||||
inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result) {
|
|
||||||
uint64_t significand = 0;
|
|
||||||
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
|
|
||||||
for (; i < dLen; i++) {
|
|
||||||
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
|
|
||||||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
|
|
||||||
break;
|
|
||||||
significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < dLen && decimals[i] >= '5') // Rounding
|
|
||||||
significand++;
|
|
||||||
|
|
||||||
int remaining = dLen - i;
|
|
||||||
const int kUlpShift = 3;
|
|
||||||
const int kUlp = 1 << kUlpShift;
|
|
||||||
int64_t error = (remaining == 0) ? 0 : kUlp / 2;
|
|
||||||
|
|
||||||
DiyFp v(significand, 0);
|
|
||||||
v = v.Normalize();
|
|
||||||
error <<= -v.e;
|
|
||||||
|
|
||||||
dExp += remaining;
|
|
||||||
|
|
||||||
int actualExp;
|
|
||||||
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
|
|
||||||
if (actualExp != dExp) {
|
|
||||||
static const DiyFp kPow10[] = {
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60), // 10^1
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57), // 10^2
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54), // 10^3
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50), // 10^4
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47), // 10^5
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44), // 10^6
|
|
||||||
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40) // 10^7
|
|
||||||
};
|
|
||||||
int adjustment = dExp - actualExp;
|
|
||||||
RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8);
|
|
||||||
v = v * kPow10[adjustment - 1];
|
|
||||||
if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit
|
|
||||||
error += kUlp / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
v = v * cachedPower;
|
|
||||||
|
|
||||||
error += kUlp + (error == 0 ? 0 : 1);
|
|
||||||
|
|
||||||
const int oldExp = v.e;
|
|
||||||
v = v.Normalize();
|
|
||||||
error <<= oldExp - v.e;
|
|
||||||
|
|
||||||
const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
|
|
||||||
int precisionSize = 64 - effectiveSignificandSize;
|
|
||||||
if (precisionSize + kUlpShift >= 64) {
|
|
||||||
int scaleExp = (precisionSize + kUlpShift) - 63;
|
|
||||||
v.f >>= scaleExp;
|
|
||||||
v.e += scaleExp;
|
|
||||||
error = (error >> scaleExp) + 1 + kUlp;
|
|
||||||
precisionSize -= scaleExp;
|
|
||||||
}
|
|
||||||
|
|
||||||
DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
|
|
||||||
const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
|
|
||||||
const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
|
|
||||||
if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
|
|
||||||
rounded.f++;
|
|
||||||
if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)
|
|
||||||
rounded.f >>= 1;
|
|
||||||
rounded.e++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = rounded.ToDouble();
|
|
||||||
|
|
||||||
return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double StrtodBigInteger(double approx, const char* decimals, int dLen, int dExp) {
|
|
||||||
RAPIDJSON_ASSERT(dLen >= 0);
|
|
||||||
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
|
|
||||||
Double a(approx);
|
|
||||||
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
|
|
||||||
if (cmp < 0)
|
|
||||||
return a.Value(); // within half ULP
|
|
||||||
else if (cmp == 0) {
|
|
||||||
// Round towards even
|
|
||||||
if (a.Significand() & 1)
|
|
||||||
return a.NextPositiveDouble();
|
|
||||||
else
|
|
||||||
return a.Value();
|
|
||||||
}
|
|
||||||
else // adjustment
|
|
||||||
return a.NextPositiveDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
|
||||||
RAPIDJSON_ASSERT(d >= 0.0);
|
|
||||||
RAPIDJSON_ASSERT(length >= 1);
|
|
||||||
|
|
||||||
double result = 0.0;
|
|
||||||
if (StrtodFast(d, p, &result))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
RAPIDJSON_ASSERT(length <= INT_MAX);
|
|
||||||
int dLen = static_cast<int>(length);
|
|
||||||
|
|
||||||
RAPIDJSON_ASSERT(length >= decimalPosition);
|
|
||||||
RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX);
|
|
||||||
int dExpAdjust = static_cast<int>(length - decimalPosition);
|
|
||||||
|
|
||||||
RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust);
|
|
||||||
int dExp = exp - dExpAdjust;
|
|
||||||
|
|
||||||
// Make sure length+dExp does not overflow
|
|
||||||
RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen);
|
|
||||||
|
|
||||||
// Trim leading zeros
|
|
||||||
while (dLen > 0 && *decimals == '0') {
|
|
||||||
dLen--;
|
|
||||||
decimals++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim trailing zeros
|
|
||||||
while (dLen > 0 && decimals[dLen - 1] == '0') {
|
|
||||||
dLen--;
|
|
||||||
dExp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dLen == 0) { // Buffer only contains zeros.
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim right-most digits
|
|
||||||
const int kMaxDecimalDigit = 767 + 1;
|
|
||||||
if (dLen > kMaxDecimalDigit) {
|
|
||||||
dExp += dLen - kMaxDecimalDigit;
|
|
||||||
dLen = kMaxDecimalDigit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If too small, underflow to zero.
|
|
||||||
// Any x <= 10^-324 is interpreted as zero.
|
|
||||||
if (dLen + dExp <= -324)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
// If too large, overflow to infinity.
|
|
||||||
// Any x >= 10^309 is interpreted as +infinity.
|
|
||||||
if (dLen + dExp > 309)
|
|
||||||
return std::numeric_limits<double>::infinity();
|
|
||||||
|
|
||||||
if (StrtodDiyFp(decimals, dLen, dExp, &result))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
|
|
||||||
return StrtodBigInteger(result, decimals, dLen, dExp);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_STRTOD_
|
|
46
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_swap.h
generated
vendored
46
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_internal_swap.h
generated
vendored
@ -1,46 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_SWAP_H_
|
|
||||||
#define RAPIDJSON_INTERNAL_SWAP_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
//! Custom swap() to avoid dependency on C++ <algorithm> header
|
|
||||||
/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
|
|
||||||
\note This has the same semantics as std::swap().
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
|
|
||||||
T tmp = a;
|
|
||||||
a = b;
|
|
||||||
b = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_INTERNAL_SWAP_H_
|
|
128
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_istreamwrapper.h
generated
vendored
128
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_istreamwrapper.h
generated
vendored
@ -1,128 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ISTREAMWRAPPER_H_
|
|
||||||
#define RAPIDJSON_ISTREAMWRAPPER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <ios>
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept.
|
|
||||||
/*!
|
|
||||||
The classes can be wrapped including but not limited to:
|
|
||||||
|
|
||||||
- \c std::istringstream
|
|
||||||
- \c std::stringstream
|
|
||||||
- \c std::wistringstream
|
|
||||||
- \c std::wstringstream
|
|
||||||
- \c std::ifstream
|
|
||||||
- \c std::fstream
|
|
||||||
- \c std::wifstream
|
|
||||||
- \c std::wfstream
|
|
||||||
|
|
||||||
\tparam StreamType Class derived from \c std::basic_istream.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename StreamType>
|
|
||||||
class BasicIStreamWrapper {
|
|
||||||
public:
|
|
||||||
typedef typename StreamType::char_type Ch;
|
|
||||||
|
|
||||||
//! Constructor.
|
|
||||||
/*!
|
|
||||||
\param stream stream opened for read.
|
|
||||||
*/
|
|
||||||
BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
|
||||||
Read();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Constructor.
|
|
||||||
/*!
|
|
||||||
\param stream stream opened for read.
|
|
||||||
\param buffer user-supplied buffer.
|
|
||||||
\param bufferSize size of buffer in bytes. Must >=4 bytes.
|
|
||||||
*/
|
|
||||||
BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
|
||||||
RAPIDJSON_ASSERT(bufferSize >= 4);
|
|
||||||
Read();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ch Peek() const { return *current_; }
|
|
||||||
Ch Take() { Ch c = *current_; Read(); return c; }
|
|
||||||
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
// For encoding detection only.
|
|
||||||
const Ch* Peek4() const {
|
|
||||||
return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BasicIStreamWrapper();
|
|
||||||
BasicIStreamWrapper(const BasicIStreamWrapper&);
|
|
||||||
BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
|
|
||||||
|
|
||||||
void Read() {
|
|
||||||
if (current_ < bufferLast_)
|
|
||||||
++current_;
|
|
||||||
else if (!eof_) {
|
|
||||||
count_ += readCount_;
|
|
||||||
readCount_ = bufferSize_;
|
|
||||||
bufferLast_ = buffer_ + readCount_ - 1;
|
|
||||||
current_ = buffer_;
|
|
||||||
|
|
||||||
if (!stream_.read(buffer_, static_cast<std::streamsize>(bufferSize_))) {
|
|
||||||
readCount_ = static_cast<size_t>(stream_.gcount());
|
|
||||||
*(bufferLast_ = buffer_ + readCount_) = '\0';
|
|
||||||
eof_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamType &stream_;
|
|
||||||
Ch peekBuffer_[4], *buffer_;
|
|
||||||
size_t bufferSize_;
|
|
||||||
Ch *bufferLast_;
|
|
||||||
Ch *current_;
|
|
||||||
size_t readCount_;
|
|
||||||
size_t count_; //!< Number of characters read
|
|
||||||
bool eof_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
|
|
||||||
typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;
|
|
||||||
|
|
||||||
#if defined(__clang__) || defined(_MSC_VER)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_ISTREAMWRAPPER_H_
|
|
70
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_memorybuffer.h
generated
vendored
70
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_memorybuffer.h
generated
vendored
@ -1,70 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_MEMORYBUFFER_H_
|
|
||||||
#define RAPIDJSON_MEMORYBUFFER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include "lottie_rapidjson_internal_stack.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Represents an in-memory output byte stream.
|
|
||||||
/*!
|
|
||||||
This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.
|
|
||||||
|
|
||||||
It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.
|
|
||||||
|
|
||||||
Differences between MemoryBuffer and StringBuffer:
|
|
||||||
1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer.
|
|
||||||
2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.
|
|
||||||
|
|
||||||
\tparam Allocator type for allocating memory buffer.
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
template <typename Allocator = CrtAllocator>
|
|
||||||
struct GenericMemoryBuffer {
|
|
||||||
typedef char Ch; // byte
|
|
||||||
|
|
||||||
GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
|
|
||||||
|
|
||||||
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
|
|
||||||
void Flush() {}
|
|
||||||
|
|
||||||
void Clear() { stack_.Clear(); }
|
|
||||||
void ShrinkToFit() { stack_.ShrinkToFit(); }
|
|
||||||
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
|
|
||||||
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
|
|
||||||
|
|
||||||
const Ch* GetBuffer() const {
|
|
||||||
return stack_.template Bottom<Ch>();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetSize() const { return stack_.GetSize(); }
|
|
||||||
|
|
||||||
static const size_t kDefaultCapacity = 256;
|
|
||||||
mutable internal::Stack<Allocator> stack_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef GenericMemoryBuffer<> MemoryBuffer;
|
|
||||||
|
|
||||||
//! Implement specialized version of PutN() with memset() for better performance.
|
|
||||||
template<>
|
|
||||||
inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {
|
|
||||||
std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_MEMORYBUFFER_H_
|
|
71
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_memorystream.h
generated
vendored
71
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_memorystream.h
generated
vendored
@ -1,71 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_MEMORYSTREAM_H_
|
|
||||||
#define RAPIDJSON_MEMORYSTREAM_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
|
||||||
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Represents an in-memory input byte stream.
|
|
||||||
/*!
|
|
||||||
This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.
|
|
||||||
|
|
||||||
It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.
|
|
||||||
|
|
||||||
Differences between MemoryStream and StringStream:
|
|
||||||
1. StringStream has encoding but MemoryStream is a byte stream.
|
|
||||||
2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.
|
|
||||||
3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
struct MemoryStream {
|
|
||||||
typedef char Ch; // byte
|
|
||||||
|
|
||||||
MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
|
|
||||||
|
|
||||||
Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; }
|
|
||||||
Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
|
|
||||||
size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
|
|
||||||
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
// For encoding detection only.
|
|
||||||
const Ch* Peek4() const {
|
|
||||||
return Tell() + 4 <= size_ ? src_ : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Ch* src_; //!< Current read position.
|
|
||||||
const Ch* begin_; //!< Original head of the string.
|
|
||||||
const Ch* end_; //!< End of stream.
|
|
||||||
size_t size_; //!< Size of the stream.
|
|
||||||
};
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_MEMORYBUFFER_H_
|
|
316
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_msinttypes_inttypes.h
generated
vendored
316
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_msinttypes_inttypes.h
generated
vendored
@ -1,316 +0,0 @@
|
|||||||
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
|
|
||||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
|
||||||
//
|
|
||||||
// Copyright (c) 2006-2013 Alexander Chemeris
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer in the
|
|
||||||
// documentation and/or other materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the product nor the names of its contributors may
|
|
||||||
// be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// The above software in this distribution may have been modified by
|
|
||||||
// THL A29 Limited ("Tencent Modifications").
|
|
||||||
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
|
|
||||||
|
|
||||||
#ifndef _MSC_VER // [
|
|
||||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
|
||||||
#endif // _MSC_VER ]
|
|
||||||
|
|
||||||
#ifndef _MSC_INTTYPES_H_ // [
|
|
||||||
#define _MSC_INTTYPES_H_
|
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_msinttypes_stdint.h"
|
|
||||||
|
|
||||||
// miloyip: VC supports inttypes.h since VC2013
|
|
||||||
#if _MSC_VER >= 1800
|
|
||||||
#include <inttypes.h>
|
|
||||||
#else
|
|
||||||
|
|
||||||
// 7.8 Format conversion of integer types
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
intmax_t quot;
|
|
||||||
intmax_t rem;
|
|
||||||
} imaxdiv_t;
|
|
||||||
|
|
||||||
// 7.8.1 Macros for format specifiers
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
|
|
||||||
|
|
||||||
// The fprintf macros for signed integers are:
|
|
||||||
#define PRId8 "d"
|
|
||||||
#define PRIi8 "i"
|
|
||||||
#define PRIdLEAST8 "d"
|
|
||||||
#define PRIiLEAST8 "i"
|
|
||||||
#define PRIdFAST8 "d"
|
|
||||||
#define PRIiFAST8 "i"
|
|
||||||
|
|
||||||
#define PRId16 "hd"
|
|
||||||
#define PRIi16 "hi"
|
|
||||||
#define PRIdLEAST16 "hd"
|
|
||||||
#define PRIiLEAST16 "hi"
|
|
||||||
#define PRIdFAST16 "hd"
|
|
||||||
#define PRIiFAST16 "hi"
|
|
||||||
|
|
||||||
#define PRId32 "I32d"
|
|
||||||
#define PRIi32 "I32i"
|
|
||||||
#define PRIdLEAST32 "I32d"
|
|
||||||
#define PRIiLEAST32 "I32i"
|
|
||||||
#define PRIdFAST32 "I32d"
|
|
||||||
#define PRIiFAST32 "I32i"
|
|
||||||
|
|
||||||
#define PRId64 "I64d"
|
|
||||||
#define PRIi64 "I64i"
|
|
||||||
#define PRIdLEAST64 "I64d"
|
|
||||||
#define PRIiLEAST64 "I64i"
|
|
||||||
#define PRIdFAST64 "I64d"
|
|
||||||
#define PRIiFAST64 "I64i"
|
|
||||||
|
|
||||||
#define PRIdMAX "I64d"
|
|
||||||
#define PRIiMAX "I64i"
|
|
||||||
|
|
||||||
#define PRIdPTR "Id"
|
|
||||||
#define PRIiPTR "Ii"
|
|
||||||
|
|
||||||
// The fprintf macros for unsigned integers are:
|
|
||||||
#define PRIo8 "o"
|
|
||||||
#define PRIu8 "u"
|
|
||||||
#define PRIx8 "x"
|
|
||||||
#define PRIX8 "X"
|
|
||||||
#define PRIoLEAST8 "o"
|
|
||||||
#define PRIuLEAST8 "u"
|
|
||||||
#define PRIxLEAST8 "x"
|
|
||||||
#define PRIXLEAST8 "X"
|
|
||||||
#define PRIoFAST8 "o"
|
|
||||||
#define PRIuFAST8 "u"
|
|
||||||
#define PRIxFAST8 "x"
|
|
||||||
#define PRIXFAST8 "X"
|
|
||||||
|
|
||||||
#define PRIo16 "ho"
|
|
||||||
#define PRIu16 "hu"
|
|
||||||
#define PRIx16 "hx"
|
|
||||||
#define PRIX16 "hX"
|
|
||||||
#define PRIoLEAST16 "ho"
|
|
||||||
#define PRIuLEAST16 "hu"
|
|
||||||
#define PRIxLEAST16 "hx"
|
|
||||||
#define PRIXLEAST16 "hX"
|
|
||||||
#define PRIoFAST16 "ho"
|
|
||||||
#define PRIuFAST16 "hu"
|
|
||||||
#define PRIxFAST16 "hx"
|
|
||||||
#define PRIXFAST16 "hX"
|
|
||||||
|
|
||||||
#define PRIo32 "I32o"
|
|
||||||
#define PRIu32 "I32u"
|
|
||||||
#define PRIx32 "I32x"
|
|
||||||
#define PRIX32 "I32X"
|
|
||||||
#define PRIoLEAST32 "I32o"
|
|
||||||
#define PRIuLEAST32 "I32u"
|
|
||||||
#define PRIxLEAST32 "I32x"
|
|
||||||
#define PRIXLEAST32 "I32X"
|
|
||||||
#define PRIoFAST32 "I32o"
|
|
||||||
#define PRIuFAST32 "I32u"
|
|
||||||
#define PRIxFAST32 "I32x"
|
|
||||||
#define PRIXFAST32 "I32X"
|
|
||||||
|
|
||||||
#define PRIo64 "I64o"
|
|
||||||
#define PRIu64 "I64u"
|
|
||||||
#define PRIx64 "I64x"
|
|
||||||
#define PRIX64 "I64X"
|
|
||||||
#define PRIoLEAST64 "I64o"
|
|
||||||
#define PRIuLEAST64 "I64u"
|
|
||||||
#define PRIxLEAST64 "I64x"
|
|
||||||
#define PRIXLEAST64 "I64X"
|
|
||||||
#define PRIoFAST64 "I64o"
|
|
||||||
#define PRIuFAST64 "I64u"
|
|
||||||
#define PRIxFAST64 "I64x"
|
|
||||||
#define PRIXFAST64 "I64X"
|
|
||||||
|
|
||||||
#define PRIoMAX "I64o"
|
|
||||||
#define PRIuMAX "I64u"
|
|
||||||
#define PRIxMAX "I64x"
|
|
||||||
#define PRIXMAX "I64X"
|
|
||||||
|
|
||||||
#define PRIoPTR "Io"
|
|
||||||
#define PRIuPTR "Iu"
|
|
||||||
#define PRIxPTR "Ix"
|
|
||||||
#define PRIXPTR "IX"
|
|
||||||
|
|
||||||
// The fscanf macros for signed integers are:
|
|
||||||
#define SCNd8 "d"
|
|
||||||
#define SCNi8 "i"
|
|
||||||
#define SCNdLEAST8 "d"
|
|
||||||
#define SCNiLEAST8 "i"
|
|
||||||
#define SCNdFAST8 "d"
|
|
||||||
#define SCNiFAST8 "i"
|
|
||||||
|
|
||||||
#define SCNd16 "hd"
|
|
||||||
#define SCNi16 "hi"
|
|
||||||
#define SCNdLEAST16 "hd"
|
|
||||||
#define SCNiLEAST16 "hi"
|
|
||||||
#define SCNdFAST16 "hd"
|
|
||||||
#define SCNiFAST16 "hi"
|
|
||||||
|
|
||||||
#define SCNd32 "ld"
|
|
||||||
#define SCNi32 "li"
|
|
||||||
#define SCNdLEAST32 "ld"
|
|
||||||
#define SCNiLEAST32 "li"
|
|
||||||
#define SCNdFAST32 "ld"
|
|
||||||
#define SCNiFAST32 "li"
|
|
||||||
|
|
||||||
#define SCNd64 "I64d"
|
|
||||||
#define SCNi64 "I64i"
|
|
||||||
#define SCNdLEAST64 "I64d"
|
|
||||||
#define SCNiLEAST64 "I64i"
|
|
||||||
#define SCNdFAST64 "I64d"
|
|
||||||
#define SCNiFAST64 "I64i"
|
|
||||||
|
|
||||||
#define SCNdMAX "I64d"
|
|
||||||
#define SCNiMAX "I64i"
|
|
||||||
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
# define SCNdPTR "I64d"
|
|
||||||
# define SCNiPTR "I64i"
|
|
||||||
#else // _WIN64 ][
|
|
||||||
# define SCNdPTR "ld"
|
|
||||||
# define SCNiPTR "li"
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
// The fscanf macros for unsigned integers are:
|
|
||||||
#define SCNo8 "o"
|
|
||||||
#define SCNu8 "u"
|
|
||||||
#define SCNx8 "x"
|
|
||||||
#define SCNX8 "X"
|
|
||||||
#define SCNoLEAST8 "o"
|
|
||||||
#define SCNuLEAST8 "u"
|
|
||||||
#define SCNxLEAST8 "x"
|
|
||||||
#define SCNXLEAST8 "X"
|
|
||||||
#define SCNoFAST8 "o"
|
|
||||||
#define SCNuFAST8 "u"
|
|
||||||
#define SCNxFAST8 "x"
|
|
||||||
#define SCNXFAST8 "X"
|
|
||||||
|
|
||||||
#define SCNo16 "ho"
|
|
||||||
#define SCNu16 "hu"
|
|
||||||
#define SCNx16 "hx"
|
|
||||||
#define SCNX16 "hX"
|
|
||||||
#define SCNoLEAST16 "ho"
|
|
||||||
#define SCNuLEAST16 "hu"
|
|
||||||
#define SCNxLEAST16 "hx"
|
|
||||||
#define SCNXLEAST16 "hX"
|
|
||||||
#define SCNoFAST16 "ho"
|
|
||||||
#define SCNuFAST16 "hu"
|
|
||||||
#define SCNxFAST16 "hx"
|
|
||||||
#define SCNXFAST16 "hX"
|
|
||||||
|
|
||||||
#define SCNo32 "lo"
|
|
||||||
#define SCNu32 "lu"
|
|
||||||
#define SCNx32 "lx"
|
|
||||||
#define SCNX32 "lX"
|
|
||||||
#define SCNoLEAST32 "lo"
|
|
||||||
#define SCNuLEAST32 "lu"
|
|
||||||
#define SCNxLEAST32 "lx"
|
|
||||||
#define SCNXLEAST32 "lX"
|
|
||||||
#define SCNoFAST32 "lo"
|
|
||||||
#define SCNuFAST32 "lu"
|
|
||||||
#define SCNxFAST32 "lx"
|
|
||||||
#define SCNXFAST32 "lX"
|
|
||||||
|
|
||||||
#define SCNo64 "I64o"
|
|
||||||
#define SCNu64 "I64u"
|
|
||||||
#define SCNx64 "I64x"
|
|
||||||
#define SCNX64 "I64X"
|
|
||||||
#define SCNoLEAST64 "I64o"
|
|
||||||
#define SCNuLEAST64 "I64u"
|
|
||||||
#define SCNxLEAST64 "I64x"
|
|
||||||
#define SCNXLEAST64 "I64X"
|
|
||||||
#define SCNoFAST64 "I64o"
|
|
||||||
#define SCNuFAST64 "I64u"
|
|
||||||
#define SCNxFAST64 "I64x"
|
|
||||||
#define SCNXFAST64 "I64X"
|
|
||||||
|
|
||||||
#define SCNoMAX "I64o"
|
|
||||||
#define SCNuMAX "I64u"
|
|
||||||
#define SCNxMAX "I64x"
|
|
||||||
#define SCNXMAX "I64X"
|
|
||||||
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
# define SCNoPTR "I64o"
|
|
||||||
# define SCNuPTR "I64u"
|
|
||||||
# define SCNxPTR "I64x"
|
|
||||||
# define SCNXPTR "I64X"
|
|
||||||
#else // _WIN64 ][
|
|
||||||
# define SCNoPTR "lo"
|
|
||||||
# define SCNuPTR "lu"
|
|
||||||
# define SCNxPTR "lx"
|
|
||||||
# define SCNXPTR "lX"
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
#endif // __STDC_FORMAT_MACROS ]
|
|
||||||
|
|
||||||
// 7.8.2 Functions for greatest-width integer types
|
|
||||||
|
|
||||||
// 7.8.2.1 The imaxabs function
|
|
||||||
#define imaxabs _abs64
|
|
||||||
|
|
||||||
// 7.8.2.2 The imaxdiv function
|
|
||||||
|
|
||||||
// This is modified version of div() function from Microsoft's div.c found
|
|
||||||
// in %MSVC.NET%\crt\src\div.c
|
|
||||||
#ifdef STATIC_IMAXDIV // [
|
|
||||||
static
|
|
||||||
#else // STATIC_IMAXDIV ][
|
|
||||||
_inline
|
|
||||||
#endif // STATIC_IMAXDIV ]
|
|
||||||
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
|
|
||||||
{
|
|
||||||
imaxdiv_t result;
|
|
||||||
|
|
||||||
result.quot = numer / denom;
|
|
||||||
result.rem = numer % denom;
|
|
||||||
|
|
||||||
if (numer < 0 && result.rem > 0) {
|
|
||||||
// did division wrong; must fix up
|
|
||||||
++result.quot;
|
|
||||||
result.rem -= denom;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7.8.2.3 The strtoimax and strtoumax functions
|
|
||||||
#define strtoimax _strtoi64
|
|
||||||
#define strtoumax _strtoui64
|
|
||||||
|
|
||||||
// 7.8.2.4 The wcstoimax and wcstoumax functions
|
|
||||||
#define wcstoimax _wcstoi64
|
|
||||||
#define wcstoumax _wcstoui64
|
|
||||||
|
|
||||||
#endif // _MSC_VER >= 1800
|
|
||||||
|
|
||||||
#endif // _MSC_INTTYPES_H_ ]
|
|
300
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_msinttypes_stdint.h
generated
vendored
300
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_msinttypes_stdint.h
generated
vendored
@ -1,300 +0,0 @@
|
|||||||
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
|
||||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
|
||||||
//
|
|
||||||
// Copyright (c) 2006-2013 Alexander Chemeris
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer in the
|
|
||||||
// documentation and/or other materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the product nor the names of its contributors may
|
|
||||||
// be used to endorse or promote products derived from this software
|
|
||||||
// without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// The above software in this distribution may have been modified by
|
|
||||||
// THL A29 Limited ("Tencent Modifications").
|
|
||||||
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
|
|
||||||
|
|
||||||
#ifndef _MSC_VER // [
|
|
||||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
|
||||||
#endif // _MSC_VER ]
|
|
||||||
|
|
||||||
#ifndef _MSC_STDINT_H_ // [
|
|
||||||
#define _MSC_STDINT_H_
|
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
|
|
||||||
#if _MSC_VER >= 1600 // [
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
|
||||||
|
|
||||||
#undef INT8_C
|
|
||||||
#undef INT16_C
|
|
||||||
#undef INT32_C
|
|
||||||
#undef INT64_C
|
|
||||||
#undef UINT8_C
|
|
||||||
#undef UINT16_C
|
|
||||||
#undef UINT32_C
|
|
||||||
#undef UINT64_C
|
|
||||||
|
|
||||||
// 7.18.4.1 Macros for minimum-width integer constants
|
|
||||||
|
|
||||||
#define INT8_C(val) val##i8
|
|
||||||
#define INT16_C(val) val##i16
|
|
||||||
#define INT32_C(val) val##i32
|
|
||||||
#define INT64_C(val) val##i64
|
|
||||||
|
|
||||||
#define UINT8_C(val) val##ui8
|
|
||||||
#define UINT16_C(val) val##ui16
|
|
||||||
#define UINT32_C(val) val##ui32
|
|
||||||
#define UINT64_C(val) val##ui64
|
|
||||||
|
|
||||||
// 7.18.4.2 Macros for greatest-width integer constants
|
|
||||||
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
|
|
||||||
// Check out Issue 9 for the details.
|
|
||||||
#ifndef INTMAX_C // [
|
|
||||||
# define INTMAX_C INT64_C
|
|
||||||
#endif // INTMAX_C ]
|
|
||||||
#ifndef UINTMAX_C // [
|
|
||||||
# define UINTMAX_C UINT64_C
|
|
||||||
#endif // UINTMAX_C ]
|
|
||||||
|
|
||||||
#endif // __STDC_CONSTANT_MACROS ]
|
|
||||||
|
|
||||||
#else // ] _MSC_VER >= 1700 [
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
|
||||||
// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}'
|
|
||||||
// or compiler would give many errors like this:
|
|
||||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
|
||||||
#if defined(__cplusplus) && !defined(_M_ARM)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
# include <wchar.h>
|
|
||||||
#if defined(__cplusplus) && !defined(_M_ARM)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
|
||||||
#ifndef _W64
|
|
||||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
|
||||||
# define _W64 __w64
|
|
||||||
# else
|
|
||||||
# define _W64
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.1 Integer types
|
|
||||||
|
|
||||||
// 7.18.1.1 Exact-width integer types
|
|
||||||
|
|
||||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
|
||||||
// realize that, e.g. char has the same size as __int8
|
|
||||||
// so we give up on __intX for them.
|
|
||||||
#if (_MSC_VER < 1300)
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#else
|
|
||||||
typedef signed __int8 int8_t;
|
|
||||||
typedef signed __int16 int16_t;
|
|
||||||
typedef signed __int32 int32_t;
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
typedef unsigned __int16 uint16_t;
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
#endif
|
|
||||||
typedef signed __int64 int64_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.1.2 Minimum-width integer types
|
|
||||||
typedef int8_t int_least8_t;
|
|
||||||
typedef int16_t int_least16_t;
|
|
||||||
typedef int32_t int_least32_t;
|
|
||||||
typedef int64_t int_least64_t;
|
|
||||||
typedef uint8_t uint_least8_t;
|
|
||||||
typedef uint16_t uint_least16_t;
|
|
||||||
typedef uint32_t uint_least32_t;
|
|
||||||
typedef uint64_t uint_least64_t;
|
|
||||||
|
|
||||||
// 7.18.1.3 Fastest minimum-width integer types
|
|
||||||
typedef int8_t int_fast8_t;
|
|
||||||
typedef int16_t int_fast16_t;
|
|
||||||
typedef int32_t int_fast32_t;
|
|
||||||
typedef int64_t int_fast64_t;
|
|
||||||
typedef uint8_t uint_fast8_t;
|
|
||||||
typedef uint16_t uint_fast16_t;
|
|
||||||
typedef uint32_t uint_fast32_t;
|
|
||||||
typedef uint64_t uint_fast64_t;
|
|
||||||
|
|
||||||
// 7.18.1.4 Integer types capable of holding object pointers
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
typedef signed __int64 intptr_t;
|
|
||||||
typedef unsigned __int64 uintptr_t;
|
|
||||||
#else // _WIN64 ][
|
|
||||||
typedef _W64 signed int intptr_t;
|
|
||||||
typedef _W64 unsigned int uintptr_t;
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
// 7.18.1.5 Greatest-width integer types
|
|
||||||
typedef int64_t intmax_t;
|
|
||||||
typedef uint64_t uintmax_t;
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.2 Limits of specified-width integer types
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
|
||||||
|
|
||||||
// 7.18.2.1 Limits of exact-width integer types
|
|
||||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
|
||||||
#define INT8_MAX _I8_MAX
|
|
||||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
|
||||||
#define INT16_MAX _I16_MAX
|
|
||||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
|
||||||
#define INT32_MAX _I32_MAX
|
|
||||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
|
||||||
#define INT64_MAX _I64_MAX
|
|
||||||
#define UINT8_MAX _UI8_MAX
|
|
||||||
#define UINT16_MAX _UI16_MAX
|
|
||||||
#define UINT32_MAX _UI32_MAX
|
|
||||||
#define UINT64_MAX _UI64_MAX
|
|
||||||
|
|
||||||
// 7.18.2.2 Limits of minimum-width integer types
|
|
||||||
#define INT_LEAST8_MIN INT8_MIN
|
|
||||||
#define INT_LEAST8_MAX INT8_MAX
|
|
||||||
#define INT_LEAST16_MIN INT16_MIN
|
|
||||||
#define INT_LEAST16_MAX INT16_MAX
|
|
||||||
#define INT_LEAST32_MIN INT32_MIN
|
|
||||||
#define INT_LEAST32_MAX INT32_MAX
|
|
||||||
#define INT_LEAST64_MIN INT64_MIN
|
|
||||||
#define INT_LEAST64_MAX INT64_MAX
|
|
||||||
#define UINT_LEAST8_MAX UINT8_MAX
|
|
||||||
#define UINT_LEAST16_MAX UINT16_MAX
|
|
||||||
#define UINT_LEAST32_MAX UINT32_MAX
|
|
||||||
#define UINT_LEAST64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
|
||||||
#define INT_FAST8_MIN INT8_MIN
|
|
||||||
#define INT_FAST8_MAX INT8_MAX
|
|
||||||
#define INT_FAST16_MIN INT16_MIN
|
|
||||||
#define INT_FAST16_MAX INT16_MAX
|
|
||||||
#define INT_FAST32_MIN INT32_MIN
|
|
||||||
#define INT_FAST32_MAX INT32_MAX
|
|
||||||
#define INT_FAST64_MIN INT64_MIN
|
|
||||||
#define INT_FAST64_MAX INT64_MAX
|
|
||||||
#define UINT_FAST8_MAX UINT8_MAX
|
|
||||||
#define UINT_FAST16_MAX UINT16_MAX
|
|
||||||
#define UINT_FAST32_MAX UINT32_MAX
|
|
||||||
#define UINT_FAST64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
# define INTPTR_MIN INT64_MIN
|
|
||||||
# define INTPTR_MAX INT64_MAX
|
|
||||||
# define UINTPTR_MAX UINT64_MAX
|
|
||||||
#else // _WIN64 ][
|
|
||||||
# define INTPTR_MIN INT32_MIN
|
|
||||||
# define INTPTR_MAX INT32_MAX
|
|
||||||
# define UINTPTR_MAX UINT32_MAX
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
// 7.18.2.5 Limits of greatest-width integer types
|
|
||||||
#define INTMAX_MIN INT64_MIN
|
|
||||||
#define INTMAX_MAX INT64_MAX
|
|
||||||
#define UINTMAX_MAX UINT64_MAX
|
|
||||||
|
|
||||||
// 7.18.3 Limits of other integer types
|
|
||||||
|
|
||||||
#ifdef _WIN64 // [
|
|
||||||
# define PTRDIFF_MIN _I64_MIN
|
|
||||||
# define PTRDIFF_MAX _I64_MAX
|
|
||||||
#else // _WIN64 ][
|
|
||||||
# define PTRDIFF_MIN _I32_MIN
|
|
||||||
# define PTRDIFF_MAX _I32_MAX
|
|
||||||
#endif // _WIN64 ]
|
|
||||||
|
|
||||||
#define SIG_ATOMIC_MIN INT_MIN
|
|
||||||
#define SIG_ATOMIC_MAX INT_MAX
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX // [
|
|
||||||
# ifdef _WIN64 // [
|
|
||||||
# define SIZE_MAX _UI64_MAX
|
|
||||||
# else // _WIN64 ][
|
|
||||||
# define SIZE_MAX _UI32_MAX
|
|
||||||
# endif // _WIN64 ]
|
|
||||||
#endif // SIZE_MAX ]
|
|
||||||
|
|
||||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
|
||||||
#ifndef WCHAR_MIN // [
|
|
||||||
# define WCHAR_MIN 0
|
|
||||||
#endif // WCHAR_MIN ]
|
|
||||||
#ifndef WCHAR_MAX // [
|
|
||||||
# define WCHAR_MAX _UI16_MAX
|
|
||||||
#endif // WCHAR_MAX ]
|
|
||||||
|
|
||||||
#define WINT_MIN 0
|
|
||||||
#define WINT_MAX _UI16_MAX
|
|
||||||
|
|
||||||
#endif // __STDC_LIMIT_MACROS ]
|
|
||||||
|
|
||||||
|
|
||||||
// 7.18.4 Limits of other integer types
|
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
|
||||||
|
|
||||||
// 7.18.4.1 Macros for minimum-width integer constants
|
|
||||||
|
|
||||||
#define INT8_C(val) val##i8
|
|
||||||
#define INT16_C(val) val##i16
|
|
||||||
#define INT32_C(val) val##i32
|
|
||||||
#define INT64_C(val) val##i64
|
|
||||||
|
|
||||||
#define UINT8_C(val) val##ui8
|
|
||||||
#define UINT16_C(val) val##ui16
|
|
||||||
#define UINT32_C(val) val##ui32
|
|
||||||
#define UINT64_C(val) val##ui64
|
|
||||||
|
|
||||||
// 7.18.4.2 Macros for greatest-width integer constants
|
|
||||||
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
|
|
||||||
// Check out Issue 9 for the details.
|
|
||||||
#ifndef INTMAX_C // [
|
|
||||||
# define INTMAX_C INT64_C
|
|
||||||
#endif // INTMAX_C ]
|
|
||||||
#ifndef UINTMAX_C // [
|
|
||||||
# define UINTMAX_C UINT64_C
|
|
||||||
#endif // UINTMAX_C ]
|
|
||||||
|
|
||||||
#endif // __STDC_CONSTANT_MACROS ]
|
|
||||||
|
|
||||||
#endif // _MSC_VER >= 1600 ]
|
|
||||||
|
|
||||||
#endif // _MSC_STDINT_H_ ]
|
|
81
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_ostreamwrapper.h
generated
vendored
81
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_ostreamwrapper.h
generated
vendored
@ -1,81 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_OSTREAMWRAPPER_H_
|
|
||||||
#define RAPIDJSON_OSTREAMWRAPPER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept.
|
|
||||||
/*!
|
|
||||||
The classes can be wrapped including but not limited to:
|
|
||||||
|
|
||||||
- \c std::ostringstream
|
|
||||||
- \c std::stringstream
|
|
||||||
- \c std::wpstringstream
|
|
||||||
- \c std::wstringstream
|
|
||||||
- \c std::ifstream
|
|
||||||
- \c std::fstream
|
|
||||||
- \c std::wofstream
|
|
||||||
- \c std::wfstream
|
|
||||||
|
|
||||||
\tparam StreamType Class derived from \c std::basic_ostream.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename StreamType>
|
|
||||||
class BasicOStreamWrapper {
|
|
||||||
public:
|
|
||||||
typedef typename StreamType::char_type Ch;
|
|
||||||
BasicOStreamWrapper(StreamType& stream) : stream_(stream) {}
|
|
||||||
|
|
||||||
void Put(Ch c) {
|
|
||||||
stream_.put(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flush() {
|
|
||||||
stream_.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not implemented
|
|
||||||
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
BasicOStreamWrapper(const BasicOStreamWrapper&);
|
|
||||||
BasicOStreamWrapper& operator=(const BasicOStreamWrapper&);
|
|
||||||
|
|
||||||
StreamType& stream_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BasicOStreamWrapper<std::ostream> OStreamWrapper;
|
|
||||||
typedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_OSTREAMWRAPPER_H_
|
|
1415
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_pointer.h
generated
vendored
1415
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_pointer.h
generated
vendored
File diff suppressed because it is too large
Load Diff
277
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_prettywriter.h
generated
vendored
277
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_prettywriter.h
generated
vendored
@ -1,277 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_PRETTYWRITER_H_
|
|
||||||
#define RAPIDJSON_PRETTYWRITER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_writer.h"
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Combination of PrettyWriter format flags.
|
|
||||||
/*! \see PrettyWriter::SetFormatOptions
|
|
||||||
*/
|
|
||||||
enum PrettyFormatOptions {
|
|
||||||
kFormatDefault = 0, //!< Default pretty formatting.
|
|
||||||
kFormatSingleLineArray = 1 //!< Format arrays on a single line.
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Writer with indentation and spacing.
|
|
||||||
/*!
|
|
||||||
\tparam OutputStream Type of output os.
|
|
||||||
\tparam SourceEncoding Encoding of source string.
|
|
||||||
\tparam TargetEncoding Encoding of output stream.
|
|
||||||
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
|
||||||
*/
|
|
||||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
|
|
||||||
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
|
|
||||||
public:
|
|
||||||
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> Base;
|
|
||||||
typedef typename Base::Ch Ch;
|
|
||||||
|
|
||||||
//! Constructor
|
|
||||||
/*! \param os Output stream.
|
|
||||||
\param allocator User supplied allocator. If it is null, it will create a private one.
|
|
||||||
\param levelDepth Initial capacity of stack.
|
|
||||||
*/
|
|
||||||
explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
|
||||||
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
|
||||||
|
|
||||||
|
|
||||||
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
|
||||||
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
PrettyWriter(PrettyWriter&& rhs) :
|
|
||||||
Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Set custom indentation.
|
|
||||||
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
|
|
||||||
\param indentCharCount Number of indent characters for each indentation level.
|
|
||||||
\note The default indentation is 4 spaces.
|
|
||||||
*/
|
|
||||||
PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
|
|
||||||
RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
|
|
||||||
indentChar_ = indentChar;
|
|
||||||
indentCharCount_ = indentCharCount;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Set pretty writer formatting options.
|
|
||||||
/*! \param options Formatting options.
|
|
||||||
*/
|
|
||||||
PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
|
|
||||||
formatOptions_ = options;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! @name Implementation of Handler
|
|
||||||
\see Handler
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); }
|
|
||||||
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
|
|
||||||
bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
|
|
||||||
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
|
|
||||||
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
|
|
||||||
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); }
|
|
||||||
bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }
|
|
||||||
|
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
|
||||||
(void)copy;
|
|
||||||
PrettyPrefix(kNumberType);
|
|
||||||
return Base::EndValue(Base::WriteString(str, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
|
||||||
(void)copy;
|
|
||||||
PrettyPrefix(kStringType);
|
|
||||||
return Base::EndValue(Base::WriteString(str, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
bool String(const std::basic_string<Ch>& str) {
|
|
||||||
return String(str.data(), SizeType(str.size()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool StartObject() {
|
|
||||||
PrettyPrefix(kObjectType);
|
|
||||||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
|
|
||||||
return Base::WriteStartObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
bool Key(const std::basic_string<Ch>& str) {
|
|
||||||
return Key(str.data(), SizeType(str.size()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool EndObject(SizeType memberCount = 0) {
|
|
||||||
(void)memberCount;
|
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
|
|
||||||
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
|
|
||||||
RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value
|
|
||||||
|
|
||||||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
|
||||||
|
|
||||||
if (!empty) {
|
|
||||||
Base::os_->Put('\n');
|
|
||||||
WriteIndent();
|
|
||||||
}
|
|
||||||
bool ret = Base::EndValue(Base::WriteEndObject());
|
|
||||||
(void)ret;
|
|
||||||
RAPIDJSON_ASSERT(ret == true);
|
|
||||||
if (Base::level_stack_.Empty()) // end of json text
|
|
||||||
Base::Flush();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartArray() {
|
|
||||||
PrettyPrefix(kArrayType);
|
|
||||||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
|
|
||||||
return Base::WriteStartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EndArray(SizeType memberCount = 0) {
|
|
||||||
(void)memberCount;
|
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
|
||||||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
|
||||||
|
|
||||||
if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
|
|
||||||
Base::os_->Put('\n');
|
|
||||||
WriteIndent();
|
|
||||||
}
|
|
||||||
bool ret = Base::EndValue(Base::WriteEndArray());
|
|
||||||
(void)ret;
|
|
||||||
RAPIDJSON_ASSERT(ret == true);
|
|
||||||
if (Base::level_stack_.Empty()) // end of json text
|
|
||||||
Base::Flush();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/*! @name Convenience extensions */
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! Simpler but slower overload.
|
|
||||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
|
||||||
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! Write a raw JSON value.
|
|
||||||
/*!
|
|
||||||
For user to write a stringified JSON as a value.
|
|
||||||
|
|
||||||
\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
|
|
||||||
\param length Length of the json.
|
|
||||||
\param type Type of the root of json.
|
|
||||||
\note When using PrettyWriter::RawValue(), the result json may not be indented correctly.
|
|
||||||
*/
|
|
||||||
bool RawValue(const Ch* json, size_t length, Type type) {
|
|
||||||
RAPIDJSON_ASSERT(json != 0);
|
|
||||||
PrettyPrefix(type);
|
|
||||||
return Base::EndValue(Base::WriteRawValue(json, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void PrettyPrefix(Type type) {
|
|
||||||
(void)type;
|
|
||||||
if (Base::level_stack_.GetSize() != 0) { // this value is not at root
|
|
||||||
typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
|
|
||||||
|
|
||||||
if (level->inArray) {
|
|
||||||
if (level->valueCount > 0) {
|
|
||||||
Base::os_->Put(','); // add comma if it is not the first element in array
|
|
||||||
if (formatOptions_ & kFormatSingleLineArray)
|
|
||||||
Base::os_->Put(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(formatOptions_ & kFormatSingleLineArray)) {
|
|
||||||
Base::os_->Put('\n');
|
|
||||||
WriteIndent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // in object
|
|
||||||
if (level->valueCount > 0) {
|
|
||||||
if (level->valueCount % 2 == 0) {
|
|
||||||
Base::os_->Put(',');
|
|
||||||
Base::os_->Put('\n');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Base::os_->Put(':');
|
|
||||||
Base::os_->Put(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Base::os_->Put('\n');
|
|
||||||
|
|
||||||
if (level->valueCount % 2 == 0)
|
|
||||||
WriteIndent();
|
|
||||||
}
|
|
||||||
if (!level->inArray && level->valueCount % 2 == 0)
|
|
||||||
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
|
|
||||||
level->valueCount++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
|
|
||||||
Base::hasRoot_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteIndent() {
|
|
||||||
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
|
|
||||||
PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ch indentChar_;
|
|
||||||
unsigned indentCharCount_;
|
|
||||||
PrettyFormatOptions formatOptions_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
|
||||||
PrettyWriter(const PrettyWriter&);
|
|
||||||
PrettyWriter& operator=(const PrettyWriter&);
|
|
||||||
};
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
|
692
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_rapidjson.h
generated
vendored
692
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_rapidjson.h
generated
vendored
@ -1,692 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_RAPIDJSON_H_
|
|
||||||
#define RAPIDJSON_RAPIDJSON_H_
|
|
||||||
|
|
||||||
/*!\file rapidjson.h
|
|
||||||
\brief common definitions and configuration
|
|
||||||
|
|
||||||
\see RAPIDJSON_CONFIG
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration
|
|
||||||
\brief Configuration macros for library features
|
|
||||||
|
|
||||||
Some RapidJSON features are configurable to adapt the library to a wide
|
|
||||||
variety of platforms, environments and usage scenarios. Most of the
|
|
||||||
features can be configured in terms of overridden or predefined
|
|
||||||
preprocessor macros at compile-time.
|
|
||||||
|
|
||||||
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
|
|
||||||
|
|
||||||
\note These macros should be given on the compiler command-line
|
|
||||||
(where applicable) to avoid inconsistent values when compiling
|
|
||||||
different translation units of a single application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdlib> // malloc(), realloc(), free(), size_t
|
|
||||||
#include <cstring> // memset(), memcpy(), memmove(), memcmp()
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_VERSION_STRING
|
|
||||||
//
|
|
||||||
// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt.
|
|
||||||
//
|
|
||||||
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
|
||||||
// token stringification
|
|
||||||
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
|
|
||||||
#define RAPIDJSON_DO_STRINGIFY(x) #x
|
|
||||||
|
|
||||||
// token concatenation
|
|
||||||
#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
|
|
||||||
#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
|
|
||||||
#define RAPIDJSON_DO_JOIN2(X, Y) X##Y
|
|
||||||
//!@endcond
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_MAJOR_VERSION
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Major version of RapidJSON in integer.
|
|
||||||
*/
|
|
||||||
/*! \def RAPIDJSON_MINOR_VERSION
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Minor version of RapidJSON in integer.
|
|
||||||
*/
|
|
||||||
/*! \def RAPIDJSON_PATCH_VERSION
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Patch version of RapidJSON in integer.
|
|
||||||
*/
|
|
||||||
/*! \def RAPIDJSON_VERSION_STRING
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Version of RapidJSON in "<major>.<minor>.<patch>" string format.
|
|
||||||
*/
|
|
||||||
#define RAPIDJSON_MAJOR_VERSION 1
|
|
||||||
#define RAPIDJSON_MINOR_VERSION 1
|
|
||||||
#define RAPIDJSON_PATCH_VERSION 0
|
|
||||||
#define RAPIDJSON_VERSION_STRING \
|
|
||||||
RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_NAMESPACE_(BEGIN|END)
|
|
||||||
/*! \def RAPIDJSON_NAMESPACE
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief provide custom rapidjson namespace
|
|
||||||
|
|
||||||
In order to avoid symbol clashes and/or "One Definition Rule" errors
|
|
||||||
between multiple inclusions of (different versions of) RapidJSON in
|
|
||||||
a single binary, users can customize the name of the main RapidJSON
|
|
||||||
namespace.
|
|
||||||
|
|
||||||
In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE
|
|
||||||
to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple
|
|
||||||
levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref
|
|
||||||
RAPIDJSON_NAMESPACE_END need to be defined as well:
|
|
||||||
|
|
||||||
\code
|
|
||||||
// in some .cpp file
|
|
||||||
#define RAPIDJSON_NAMESPACE my::rapidjson
|
|
||||||
#define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson {
|
|
||||||
#define RAPIDJSON_NAMESPACE_END } }
|
|
||||||
#include "rapidjson/..."
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\see rapidjson
|
|
||||||
*/
|
|
||||||
/*! \def RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief provide custom rapidjson namespace (opening expression)
|
|
||||||
\see RAPIDJSON_NAMESPACE
|
|
||||||
*/
|
|
||||||
/*! \def RAPIDJSON_NAMESPACE_END
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief provide custom rapidjson namespace (closing expression)
|
|
||||||
\see RAPIDJSON_NAMESPACE
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_NAMESPACE
|
|
||||||
#define RAPIDJSON_NAMESPACE rapidjson
|
|
||||||
#endif
|
|
||||||
#ifndef RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE {
|
|
||||||
#endif
|
|
||||||
#ifndef RAPIDJSON_NAMESPACE_END
|
|
||||||
#define RAPIDJSON_NAMESPACE_END }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_HAS_STDSTRING
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_HAS_STDSTRING
|
|
||||||
#ifdef RAPIDJSON_DOXYGEN_RUNNING
|
|
||||||
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
|
|
||||||
#endif
|
|
||||||
/*! \def RAPIDJSON_HAS_STDSTRING
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Enable RapidJSON support for \c std::string
|
|
||||||
|
|
||||||
By defining this preprocessor symbol to \c 1, several convenience functions for using
|
|
||||||
\ref rapidjson::GenericValue with \c std::string are enabled, especially
|
|
||||||
for construction and comparison.
|
|
||||||
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#endif // !defined(RAPIDJSON_HAS_STDSTRING)
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
#include <string>
|
|
||||||
#endif // RAPIDJSON_HAS_STDSTRING
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_NO_INT64DEFINE
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_NO_INT64DEFINE
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Use external 64-bit integer types.
|
|
||||||
|
|
||||||
RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types
|
|
||||||
to be available at global scope.
|
|
||||||
|
|
||||||
If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to
|
|
||||||
prevent RapidJSON from defining its own types.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_NO_INT64DEFINE
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
|
|
||||||
#include "lottie_rapidjson_msinttypes_stdint.h"
|
|
||||||
#include "lottie_rapidjson_msinttypes_inttypes.h"
|
|
||||||
#else
|
|
||||||
// Other compilers should have this.
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
//!@endcond
|
|
||||||
#ifdef RAPIDJSON_DOXYGEN_RUNNING
|
|
||||||
#define RAPIDJSON_NO_INT64DEFINE
|
|
||||||
#endif
|
|
||||||
#endif // RAPIDJSON_NO_INT64TYPEDEF
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_FORCEINLINE
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_FORCEINLINE
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
|
||||||
#if defined(_MSC_VER) && defined(NDEBUG)
|
|
||||||
#define RAPIDJSON_FORCEINLINE __forceinline
|
|
||||||
#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG)
|
|
||||||
#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_FORCEINLINE
|
|
||||||
#endif
|
|
||||||
//!@endcond
|
|
||||||
#endif // RAPIDJSON_FORCEINLINE
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_ENDIAN
|
|
||||||
#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
|
|
||||||
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
|
|
||||||
|
|
||||||
//! Endianness of the machine.
|
|
||||||
/*!
|
|
||||||
\def RAPIDJSON_ENDIAN
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
|
|
||||||
GCC 4.6 provided macro for detecting endianness of the target machine. But other
|
|
||||||
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
|
|
||||||
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
|
|
||||||
|
|
||||||
Default detection implemented with reference to
|
|
||||||
\li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
|
|
||||||
\li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_ENDIAN
|
|
||||||
// Detect with GCC 4.6's macro
|
|
||||||
# ifdef __BYTE_ORDER__
|
|
||||||
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
|
||||||
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
|
||||||
# else
|
|
||||||
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
|
||||||
# endif // __BYTE_ORDER__
|
|
||||||
// Detect with GLIBC's endian.h
|
|
||||||
# elif defined(__GLIBC__)
|
|
||||||
# include <endian.h>
|
|
||||||
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
|
||||||
# elif (__BYTE_ORDER == __BIG_ENDIAN)
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
|
||||||
# else
|
|
||||||
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
|
||||||
# endif // __GLIBC__
|
|
||||||
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
|
|
||||||
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
|
||||||
# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
|
||||||
// Detect with architecture macros
|
|
||||||
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
|
||||||
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
|
||||||
# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
|
||||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
|
||||||
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
|
||||||
# define RAPIDJSON_ENDIAN
|
|
||||||
# else
|
|
||||||
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
|
||||||
# endif
|
|
||||||
#endif // RAPIDJSON_ENDIAN
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_64BIT
|
|
||||||
|
|
||||||
//! Whether using 64-bit architecture
|
|
||||||
#ifndef RAPIDJSON_64BIT
|
|
||||||
#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__)
|
|
||||||
#define RAPIDJSON_64BIT 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_64BIT 0
|
|
||||||
#endif
|
|
||||||
#endif // RAPIDJSON_64BIT
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_ALIGN
|
|
||||||
|
|
||||||
//! Data alignment of the machine.
|
|
||||||
/*! \ingroup RAPIDJSON_CONFIG
|
|
||||||
\param x pointer to align
|
|
||||||
|
|
||||||
Some machines require strict data alignment. The default is 8 bytes.
|
|
||||||
User can customize by defining the RAPIDJSON_ALIGN function macro.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_ALIGN
|
|
||||||
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_UINT64_C2
|
|
||||||
|
|
||||||
//! Construct a 64-bit literal by a pair of 32-bit integer.
|
|
||||||
/*!
|
|
||||||
64-bit literal with or without ULL suffix is prone to compiler warnings.
|
|
||||||
UINT64_C() is C macro which cause compilation problems.
|
|
||||||
Use this macro to define 64-bit constants by a pair of 32-bit integer.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_UINT64_C2
|
|
||||||
#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
|
||||||
|
|
||||||
//! Use only lower 48-bit address for some pointers.
|
|
||||||
/*!
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
|
|
||||||
This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address.
|
|
||||||
The higher 16-bit can be used for storing other data.
|
|
||||||
\c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
|
||||||
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
|
|
||||||
#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0
|
|
||||||
#endif
|
|
||||||
#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
|
||||||
|
|
||||||
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1
|
|
||||||
#if RAPIDJSON_64BIT != 1
|
|
||||||
#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1
|
|
||||||
#endif
|
|
||||||
#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))
|
|
||||||
#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x))
|
|
||||||
#define RAPIDJSON_GETPOINTER(type, p) (p)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_SIMD
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief Enable SSE2/SSE4.2/Neon optimization.
|
|
||||||
|
|
||||||
RapidJSON supports optimized implementations for some parsing operations
|
|
||||||
based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel
|
|
||||||
or ARM compatible processors.
|
|
||||||
|
|
||||||
To enable these optimizations, three different symbols can be defined;
|
|
||||||
\code
|
|
||||||
// Enable SSE2 optimization.
|
|
||||||
#define RAPIDJSON_SSE2
|
|
||||||
|
|
||||||
// Enable SSE4.2 optimization.
|
|
||||||
#define RAPIDJSON_SSE42
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
// Enable ARM Neon optimization.
|
|
||||||
#define RAPIDJSON_NEON
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined.
|
|
||||||
|
|
||||||
If any of these symbols is defined, RapidJSON defines the macro
|
|
||||||
\c RAPIDJSON_SIMD to indicate the availability of the optimized code.
|
|
||||||
*/
|
|
||||||
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
|
|
||||||
|| defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)
|
|
||||||
#define RAPIDJSON_SIMD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_NO_SIZETYPEDEFINE
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
|
|
||||||
/*! \def RAPIDJSON_NO_SIZETYPEDEFINE
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief User-provided \c SizeType definition.
|
|
||||||
|
|
||||||
In order to avoid using 32-bit size types for indexing strings and arrays,
|
|
||||||
define this preprocessor symbol and provide the type rapidjson::SizeType
|
|
||||||
before including RapidJSON:
|
|
||||||
\code
|
|
||||||
#define RAPIDJSON_NO_SIZETYPEDEFINE
|
|
||||||
namespace rapidjson { typedef ::std::size_t SizeType; }
|
|
||||||
#include "rapidjson/..."
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\see rapidjson::SizeType
|
|
||||||
*/
|
|
||||||
#ifdef RAPIDJSON_DOXYGEN_RUNNING
|
|
||||||
#define RAPIDJSON_NO_SIZETYPEDEFINE
|
|
||||||
#endif
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
//! Size type (for string lengths, array sizes, etc.)
|
|
||||||
/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,
|
|
||||||
instead of using \c size_t. Users may override the SizeType by defining
|
|
||||||
\ref RAPIDJSON_NO_SIZETYPEDEFINE.
|
|
||||||
*/
|
|
||||||
typedef unsigned SizeType;
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// always import std::size_t to rapidjson namespace
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
using std::size_t;
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_ASSERT
|
|
||||||
|
|
||||||
//! Assertion.
|
|
||||||
/*! \ingroup RAPIDJSON_CONFIG
|
|
||||||
By default, rapidjson uses C \c assert() for internal assertions.
|
|
||||||
User can override it by defining RAPIDJSON_ASSERT(x) macro.
|
|
||||||
|
|
||||||
\note Parsing errors are handled and can be customized by the
|
|
||||||
\ref RAPIDJSON_ERRORS APIs.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_ASSERT
|
|
||||||
#include <cassert>
|
|
||||||
#define RAPIDJSON_ASSERT(x) assert(x)
|
|
||||||
#endif // RAPIDJSON_ASSERT
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_STATIC_ASSERT
|
|
||||||
|
|
||||||
// Prefer C++11 static_assert, if available
|
|
||||||
#ifndef RAPIDJSON_STATIC_ASSERT
|
|
||||||
#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
|
|
||||||
#define RAPIDJSON_STATIC_ASSERT(x) \
|
|
||||||
static_assert(x, RAPIDJSON_STRINGIFY(x))
|
|
||||||
#endif // C++11
|
|
||||||
#endif // RAPIDJSON_STATIC_ASSERT
|
|
||||||
|
|
||||||
// Adopt C++03 implementation from boost
|
|
||||||
#ifndef RAPIDJSON_STATIC_ASSERT
|
|
||||||
#ifndef __clang__
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
|
||||||
#endif
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
template <bool x> struct STATIC_ASSERTION_FAILURE;
|
|
||||||
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
|
||||||
template <size_t x> struct StaticAssertTest {};
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
|
||||||
#endif
|
|
||||||
#ifndef __clang__
|
|
||||||
//!@endcond
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_STATIC_ASSERT
|
|
||||||
\brief (Internal) macro to check for conditions at compile-time
|
|
||||||
\param x compile-time condition
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define RAPIDJSON_STATIC_ASSERT(x) \
|
|
||||||
typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \
|
|
||||||
sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \
|
|
||||||
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
|
||||||
#endif // RAPIDJSON_STATIC_ASSERT
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY
|
|
||||||
|
|
||||||
//! Compiler branching hint for expression with high probability to be true.
|
|
||||||
/*!
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\param x Boolean expression likely to be true.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_LIKELY
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_LIKELY(x) (x)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Compiler branching hint for expression with low probability to be true.
|
|
||||||
/*!
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\param x Boolean expression unlikely to be true.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_UNLIKELY
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_UNLIKELY(x) (x)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Helpers
|
|
||||||
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
|
||||||
|
|
||||||
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
|
||||||
#define RAPIDJSON_MULTILINEMACRO_END \
|
|
||||||
} while((void)0, 0)
|
|
||||||
|
|
||||||
// adopted from Boost
|
|
||||||
#define RAPIDJSON_VERSION_CODE(x,y,z) \
|
|
||||||
(((x)*100000) + ((y)*100) + (z))
|
|
||||||
|
|
||||||
#if defined(__has_builtin)
|
|
||||||
#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x)
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_BUILTIN(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define RAPIDJSON_GNUC \
|
|
||||||
RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))
|
|
||||||
|
|
||||||
#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
|
|
||||||
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
|
|
||||||
#define RAPIDJSON_DIAG_OFF(x) \
|
|
||||||
RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))
|
|
||||||
|
|
||||||
// push/pop support in Clang and GCC>=4.6
|
|
||||||
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0))
|
|
||||||
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
|
|
||||||
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
|
|
||||||
#else // GCC >= 4.2, < 4.6
|
|
||||||
#define RAPIDJSON_DIAG_PUSH /* ignored */
|
|
||||||
#define RAPIDJSON_DIAG_POP /* ignored */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
|
|
||||||
// pragma (MSVC specific)
|
|
||||||
#define RAPIDJSON_PRAGMA(x) __pragma(x)
|
|
||||||
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
|
|
||||||
|
|
||||||
#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
|
|
||||||
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
|
|
||||||
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define RAPIDJSON_DIAG_OFF(x) /* ignored */
|
|
||||||
#define RAPIDJSON_DIAG_PUSH /* ignored */
|
|
||||||
#define RAPIDJSON_DIAG_POP /* ignored */
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_DIAG_*
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// C++11 features
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
#if defined(__clang__)
|
|
||||||
#if __has_feature(cxx_rvalue_references) && \
|
|
||||||
(defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
|
|
||||||
#endif
|
|
||||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
|
|
||||||
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
|
||||||
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
|
|
||||||
#endif
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
|
|
||||||
#if defined(__clang__)
|
|
||||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
|
|
||||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
|
||||||
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
|
||||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
|
||||||
#define RAPIDJSON_NOEXCEPT noexcept
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_NOEXCEPT /* noexcept */
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
|
||||||
|
|
||||||
// no automatic detection, yet
|
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
|
||||||
#if (defined(_MSC_VER) && _MSC_VER >= 1700)
|
|
||||||
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
|
|
||||||
#if defined(__clang__)
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
|
|
||||||
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
|
|
||||||
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
|
|
||||||
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
|
|
||||||
#endif
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// C++17 features
|
|
||||||
|
|
||||||
#if defined(__has_cpp_attribute)
|
|
||||||
# if __has_cpp_attribute(fallthrough)
|
|
||||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
|
|
||||||
# else
|
|
||||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//!@endcond
|
|
||||||
|
|
||||||
//! Assertion (in non-throwing contexts).
|
|
||||||
/*! \ingroup RAPIDJSON_CONFIG
|
|
||||||
Some functions provide a \c noexcept guarantee, if the compiler supports it.
|
|
||||||
In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to
|
|
||||||
throw an exception. This macro adds a separate customization point for
|
|
||||||
such cases.
|
|
||||||
|
|
||||||
Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is
|
|
||||||
supported, and to \ref RAPIDJSON_ASSERT otherwise.
|
|
||||||
*/
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RAPIDJSON_NOEXCEPT_ASSERT
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_NOEXCEPT_ASSERT
|
|
||||||
#ifdef RAPIDJSON_ASSERT_THROWS
|
|
||||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
|
|
||||||
#else
|
|
||||||
#include <cassert>
|
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x)
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
|
||||||
#else
|
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
|
||||||
#endif // RAPIDJSON_ASSERT_THROWS
|
|
||||||
#endif // RAPIDJSON_NOEXCEPT_ASSERT
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// malloc/realloc/free
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_MALLOC
|
|
||||||
///! customization point for global \c malloc
|
|
||||||
#define RAPIDJSON_MALLOC(size) std::malloc(size)
|
|
||||||
#endif
|
|
||||||
#ifndef RAPIDJSON_REALLOC
|
|
||||||
///! customization point for global \c realloc
|
|
||||||
#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
|
|
||||||
#endif
|
|
||||||
#ifndef RAPIDJSON_FREE
|
|
||||||
///! customization point for global \c free
|
|
||||||
#define RAPIDJSON_FREE(ptr) std::free(ptr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// new/delete
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_NEW
|
|
||||||
///! customization point for global \c new
|
|
||||||
#define RAPIDJSON_NEW(TypeName) new TypeName
|
|
||||||
#endif
|
|
||||||
#ifndef RAPIDJSON_DELETE
|
|
||||||
///! customization point for global \c delete
|
|
||||||
#define RAPIDJSON_DELETE(x) delete x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Type
|
|
||||||
|
|
||||||
/*! \namespace rapidjson
|
|
||||||
\brief main RapidJSON namespace
|
|
||||||
\see RAPIDJSON_NAMESPACE
|
|
||||||
*/
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Type of JSON value
|
|
||||||
enum Type {
|
|
||||||
kNullType = 0, //!< null
|
|
||||||
kFalseType = 1, //!< false
|
|
||||||
kTrueType = 2, //!< true
|
|
||||||
kObjectType = 3, //!< object
|
|
||||||
kArrayType = 4, //!< array
|
|
||||||
kStringType = 5, //!< string
|
|
||||||
kNumberType = 6 //!< number
|
|
||||||
};
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
|
2244
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_reader.h
generated
vendored
2244
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_reader.h
generated
vendored
File diff suppressed because it is too large
Load Diff
2496
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_schema.h
generated
vendored
2496
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_schema.h
generated
vendored
File diff suppressed because it is too large
Load Diff
223
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_stream.h
generated
vendored
223
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_stream.h
generated
vendored
@ -1,223 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_rapidjson.h"
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_STREAM_H_
|
|
||||||
#define RAPIDJSON_STREAM_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_encodings.h"
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Stream
|
|
||||||
|
|
||||||
/*! \class rapidjson::Stream
|
|
||||||
\brief Concept for reading and writing characters.
|
|
||||||
|
|
||||||
For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
|
|
||||||
|
|
||||||
For write-only stream, only need to implement Put() and Flush().
|
|
||||||
|
|
||||||
\code
|
|
||||||
concept Stream {
|
|
||||||
typename Ch; //!< Character type of the stream.
|
|
||||||
|
|
||||||
//! Read the current character from stream without moving the read cursor.
|
|
||||||
Ch Peek() const;
|
|
||||||
|
|
||||||
//! Read the current character from stream and moving the read cursor to next character.
|
|
||||||
Ch Take();
|
|
||||||
|
|
||||||
//! Get the current read cursor.
|
|
||||||
//! \return Number of characters read from start.
|
|
||||||
size_t Tell();
|
|
||||||
|
|
||||||
//! Begin writing operation at the current read pointer.
|
|
||||||
//! \return The begin writer pointer.
|
|
||||||
Ch* PutBegin();
|
|
||||||
|
|
||||||
//! Write a character.
|
|
||||||
void Put(Ch c);
|
|
||||||
|
|
||||||
//! Flush the buffer.
|
|
||||||
void Flush();
|
|
||||||
|
|
||||||
//! End the writing operation.
|
|
||||||
//! \param begin The begin write pointer returned by PutBegin().
|
|
||||||
//! \return Number of characters written.
|
|
||||||
size_t PutEnd(Ch* begin);
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
//! Provides additional information for stream.
|
|
||||||
/*!
|
|
||||||
By using traits pattern, this type provides a default configuration for stream.
|
|
||||||
For custom stream, this type can be specialized for other configuration.
|
|
||||||
See TEST(Reader, CustomStringStream) in readertest.cpp for example.
|
|
||||||
*/
|
|
||||||
template<typename Stream>
|
|
||||||
struct StreamTraits {
|
|
||||||
//! Whether to make local copy of stream for optimization during parsing.
|
|
||||||
/*!
|
|
||||||
By default, for safety, streams do not use local copy optimization.
|
|
||||||
Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
|
|
||||||
*/
|
|
||||||
enum { copyOptimization = 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Reserve n characters for writing to a stream.
|
|
||||||
template<typename Stream>
|
|
||||||
inline void PutReserve(Stream& stream, size_t count) {
|
|
||||||
(void)stream;
|
|
||||||
(void)count;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Write character to a stream, presuming buffer is reserved.
|
|
||||||
template<typename Stream>
|
|
||||||
inline void PutUnsafe(Stream& stream, typename Stream::Ch c) {
|
|
||||||
stream.Put(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Put N copies of a character to a stream.
|
|
||||||
template<typename Stream, typename Ch>
|
|
||||||
inline void PutN(Stream& stream, Ch c, size_t n) {
|
|
||||||
PutReserve(stream, n);
|
|
||||||
for (size_t i = 0; i < n; i++)
|
|
||||||
PutUnsafe(stream, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// GenericStreamWrapper
|
|
||||||
|
|
||||||
//! A Stream Wrapper
|
|
||||||
/*! \tThis string stream is a wrapper for any stream by just forwarding any
|
|
||||||
\treceived message to the origin stream.
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename InputStream, typename Encoding = UTF8<> >
|
|
||||||
class GenericStreamWrapper {
|
|
||||||
public:
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
GenericStreamWrapper(InputStream& is): is_(is) {}
|
|
||||||
|
|
||||||
Ch Peek() const { return is_.Peek(); }
|
|
||||||
Ch Take() { return is_.Take(); }
|
|
||||||
size_t Tell() { return is_.Tell(); }
|
|
||||||
Ch* PutBegin() { return is_.PutBegin(); }
|
|
||||||
void Put(Ch ch) { is_.Put(ch); }
|
|
||||||
void Flush() { is_.Flush(); }
|
|
||||||
size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); }
|
|
||||||
|
|
||||||
// wrapper for MemoryStream
|
|
||||||
const Ch* Peek4() const { return is_.Peek4(); }
|
|
||||||
|
|
||||||
// wrapper for AutoUTFInputStream
|
|
||||||
UTFType GetType() const { return is_.GetType(); }
|
|
||||||
bool HasBOM() const { return is_.HasBOM(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
InputStream& is_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// StringStream
|
|
||||||
|
|
||||||
//! Read-only string stream.
|
|
||||||
/*! \note implements Stream concept
|
|
||||||
*/
|
|
||||||
template <typename Encoding>
|
|
||||||
struct GenericStringStream {
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
GenericStringStream(const Ch *src) : src_(src), head_(src) {}
|
|
||||||
|
|
||||||
Ch Peek() const { return *src_; }
|
|
||||||
Ch Take() { return *src_++; }
|
|
||||||
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
|
||||||
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
|
|
||||||
const Ch* src_; //!< Current read position.
|
|
||||||
const Ch* head_; //!< Original head of the string.
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Encoding>
|
|
||||||
struct StreamTraits<GenericStringStream<Encoding> > {
|
|
||||||
enum { copyOptimization = 1 };
|
|
||||||
};
|
|
||||||
|
|
||||||
//! String stream with UTF8 encoding.
|
|
||||||
typedef GenericStringStream<UTF8<> > StringStream;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// InsituStringStream
|
|
||||||
|
|
||||||
//! A read-write string stream.
|
|
||||||
/*! This string stream is particularly designed for in-situ parsing.
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
template <typename Encoding>
|
|
||||||
struct GenericInsituStringStream {
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
|
|
||||||
|
|
||||||
// Read
|
|
||||||
Ch Peek() { return *src_; }
|
|
||||||
Ch Take() { return *src_++; }
|
|
||||||
size_t Tell() { return static_cast<size_t>(src_ - head_); }
|
|
||||||
|
|
||||||
// Write
|
|
||||||
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
|
|
||||||
|
|
||||||
Ch* PutBegin() { return dst_ = src_; }
|
|
||||||
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
|
|
||||||
void Flush() {}
|
|
||||||
|
|
||||||
Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
|
|
||||||
void Pop(size_t count) { dst_ -= count; }
|
|
||||||
|
|
||||||
Ch* src_;
|
|
||||||
Ch* dst_;
|
|
||||||
Ch* head_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Encoding>
|
|
||||||
struct StreamTraits<GenericInsituStringStream<Encoding> > {
|
|
||||||
enum { copyOptimization = 1 };
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Insitu string stream with UTF8 encoding.
|
|
||||||
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_STREAM_H_
|
|
121
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_stringbuffer.h
generated
vendored
121
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_stringbuffer.h
generated
vendored
@ -1,121 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_STRINGBUFFER_H_
|
|
||||||
#define RAPIDJSON_STRINGBUFFER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include "lottie_rapidjson_internal_stack.h"
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
#include <utility> // std::move
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_internal_stack.h"
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
//! Represents an in-memory output stream.
|
|
||||||
/*!
|
|
||||||
\tparam Encoding Encoding of the stream.
|
|
||||||
\tparam Allocator type for allocating memory buffer.
|
|
||||||
\note implements Stream concept
|
|
||||||
*/
|
|
||||||
template <typename Encoding, typename Allocator = CrtAllocator>
|
|
||||||
class GenericStringBuffer {
|
|
||||||
public:
|
|
||||||
typedef typename Encoding::Ch Ch;
|
|
||||||
|
|
||||||
GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
|
|
||||||
GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
|
|
||||||
if (&rhs != this)
|
|
||||||
stack_ = std::move(rhs.stack_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
|
|
||||||
void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }
|
|
||||||
void Flush() {}
|
|
||||||
|
|
||||||
void Clear() { stack_.Clear(); }
|
|
||||||
void ShrinkToFit() {
|
|
||||||
// Push and pop a null terminator. This is safe.
|
|
||||||
*stack_.template Push<Ch>() = '\0';
|
|
||||||
stack_.ShrinkToFit();
|
|
||||||
stack_.template Pop<Ch>(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
|
|
||||||
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
|
|
||||||
Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }
|
|
||||||
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
|
|
||||||
|
|
||||||
const Ch* GetString() const {
|
|
||||||
// Push and pop a null terminator. This is safe.
|
|
||||||
*stack_.template Push<Ch>() = '\0';
|
|
||||||
stack_.template Pop<Ch>(1);
|
|
||||||
|
|
||||||
return stack_.template Bottom<Ch>();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Get the size of string in bytes in the string buffer.
|
|
||||||
size_t GetSize() const { return stack_.GetSize(); }
|
|
||||||
|
|
||||||
//! Get the length of string in Ch in the string buffer.
|
|
||||||
size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }
|
|
||||||
|
|
||||||
static const size_t kDefaultCapacity = 256;
|
|
||||||
mutable internal::Stack<Allocator> stack_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
|
||||||
GenericStringBuffer(const GenericStringBuffer&);
|
|
||||||
GenericStringBuffer& operator=(const GenericStringBuffer&);
|
|
||||||
};
|
|
||||||
|
|
||||||
//! String buffer with UTF8 encoding
|
|
||||||
typedef GenericStringBuffer<UTF8<> > StringBuffer;
|
|
||||||
|
|
||||||
template<typename Encoding, typename Allocator>
|
|
||||||
inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {
|
|
||||||
stream.Reserve(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Encoding, typename Allocator>
|
|
||||||
inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {
|
|
||||||
stream.PutUnsafe(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Implement specialized version of PutN() with memset() for better performance.
|
|
||||||
template<>
|
|
||||||
inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
|
|
||||||
std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_STRINGBUFFER_H_
|
|
710
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_writer.h
generated
vendored
710
vendor/github.com/Benau/go_rlottie/lottie_rapidjson_writer.h
generated
vendored
@ -1,710 +0,0 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://opensource.org/licenses/MIT
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#ifndef RAPIDJSON_WRITER_H_
|
|
||||||
#define RAPIDJSON_WRITER_H_
|
|
||||||
|
|
||||||
#include "lottie_rapidjson_stream.h"
|
|
||||||
#include "lottie_rapidjson_internal_clzll.h"
|
|
||||||
#include "lottie_rapidjson_internal_meta.h"
|
|
||||||
#include "lottie_rapidjson_internal_stack.h"
|
|
||||||
#include "lottie_rapidjson_internal_strfunc.h"
|
|
||||||
#include "lottie_rapidjson_internal_dtoa.h"
|
|
||||||
#include "lottie_rapidjson_internal_itoa.h"
|
|
||||||
#include "lottie_rapidjson_stringbuffer.h"
|
|
||||||
#include <new> // placement new
|
|
||||||
|
|
||||||
#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
|
|
||||||
#include <intrin.h>
|
|
||||||
#pragma intrinsic(_BitScanForward)
|
|
||||||
#endif
|
|
||||||
#ifdef RAPIDJSON_SSE42
|
|
||||||
#include <nmmintrin.h>
|
|
||||||
#elif defined(RAPIDJSON_SSE2)
|
|
||||||
#include <emmintrin.h>
|
|
||||||
#elif defined(RAPIDJSON_NEON)
|
|
||||||
#include <arm_neon.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
|
||||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
|
||||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// WriteFlag
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS
|
|
||||||
\ingroup RAPIDJSON_CONFIG
|
|
||||||
\brief User-defined kWriteDefaultFlags definition.
|
|
||||||
|
|
||||||
User can define this as any \c WriteFlag combinations.
|
|
||||||
*/
|
|
||||||
#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
|
|
||||||
#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Combination of writeFlags
|
|
||||||
enum WriteFlag {
|
|
||||||
kWriteNoFlags = 0, //!< No flags are set.
|
|
||||||
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
|
|
||||||
kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
|
|
||||||
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
|
|
||||||
};
|
|
||||||
|
|
||||||
//! JSON writer
|
|
||||||
/*! Writer implements the concept Handler.
|
|
||||||
It generates JSON text by events to an output os.
|
|
||||||
|
|
||||||
User may programmatically calls the functions of a writer to generate JSON text.
|
|
||||||
|
|
||||||
On the other side, a writer can also be passed to objects that generates events,
|
|
||||||
|
|
||||||
for example Reader::Parse() and Document::Accept().
|
|
||||||
|
|
||||||
\tparam OutputStream Type of output stream.
|
|
||||||
\tparam SourceEncoding Encoding of source string.
|
|
||||||
\tparam TargetEncoding Encoding of output stream.
|
|
||||||
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
|
||||||
\note implements Handler concept
|
|
||||||
*/
|
|
||||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
|
|
||||||
class Writer {
|
|
||||||
public:
|
|
||||||
typedef typename SourceEncoding::Ch Ch;
|
|
||||||
|
|
||||||
static const int kDefaultMaxDecimalPlaces = 324;
|
|
||||||
|
|
||||||
//! Constructor
|
|
||||||
/*! \param os Output stream.
|
|
||||||
\param stackAllocator User supplied allocator. If it is null, it will create a private one.
|
|
||||||
\param levelDepth Initial capacity of stack.
|
|
||||||
*/
|
|
||||||
explicit
|
|
||||||
Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
|
||||||
os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
|
|
||||||
|
|
||||||
explicit
|
|
||||||
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
|
||||||
os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
Writer(Writer&& rhs) :
|
|
||||||
os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {
|
|
||||||
rhs.os_ = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! Reset the writer with a new stream.
|
|
||||||
/*!
|
|
||||||
This function reset the writer with a new stream and default settings,
|
|
||||||
in order to make a Writer object reusable for output multiple JSONs.
|
|
||||||
|
|
||||||
\param os New output stream.
|
|
||||||
\code
|
|
||||||
Writer<OutputStream> writer(os1);
|
|
||||||
writer.StartObject();
|
|
||||||
// ...
|
|
||||||
writer.EndObject();
|
|
||||||
|
|
||||||
writer.Reset(os2);
|
|
||||||
writer.StartObject();
|
|
||||||
// ...
|
|
||||||
writer.EndObject();
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
void Reset(OutputStream& os) {
|
|
||||||
os_ = &os;
|
|
||||||
hasRoot_ = false;
|
|
||||||
level_stack_.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Checks whether the output is a complete JSON.
|
|
||||||
/*!
|
|
||||||
A complete JSON has a complete root object or array.
|
|
||||||
*/
|
|
||||||
bool IsComplete() const {
|
|
||||||
return hasRoot_ && level_stack_.Empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetMaxDecimalPlaces() const {
|
|
||||||
return maxDecimalPlaces_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Sets the maximum number of decimal places for double output.
|
|
||||||
/*!
|
|
||||||
This setting truncates the output with specified number of decimal places.
|
|
||||||
|
|
||||||
For example,
|
|
||||||
|
|
||||||
\code
|
|
||||||
writer.SetMaxDecimalPlaces(3);
|
|
||||||
writer.StartArray();
|
|
||||||
writer.Double(0.12345); // "0.123"
|
|
||||||
writer.Double(0.0001); // "0.0"
|
|
||||||
writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent)
|
|
||||||
writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent)
|
|
||||||
writer.EndArray();
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
The default setting does not truncate any decimal places. You can restore to this setting by calling
|
|
||||||
\code
|
|
||||||
writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
void SetMaxDecimalPlaces(int maxDecimalPlaces) {
|
|
||||||
maxDecimalPlaces_ = maxDecimalPlaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!@name Implementation of Handler
|
|
||||||
\see Handler
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
bool Null() { Prefix(kNullType); return EndValue(WriteNull()); }
|
|
||||||
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }
|
|
||||||
bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); }
|
|
||||||
bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); }
|
|
||||||
bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }
|
|
||||||
bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }
|
|
||||||
|
|
||||||
//! Writes the given \c double value to the stream
|
|
||||||
/*!
|
|
||||||
\param d The value to be written.
|
|
||||||
\return Whether it is succeed.
|
|
||||||
*/
|
|
||||||
bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); }
|
|
||||||
|
|
||||||
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
|
||||||
(void)copy;
|
|
||||||
Prefix(kNumberType);
|
|
||||||
return EndValue(WriteString(str, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
|
||||||
RAPIDJSON_ASSERT(str != 0);
|
|
||||||
(void)copy;
|
|
||||||
Prefix(kStringType);
|
|
||||||
return EndValue(WriteString(str, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
bool String(const std::basic_string<Ch>& str) {
|
|
||||||
return String(str.data(), SizeType(str.size()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool StartObject() {
|
|
||||||
Prefix(kObjectType);
|
|
||||||
new (level_stack_.template Push<Level>()) Level(false);
|
|
||||||
return WriteStartObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
bool Key(const std::basic_string<Ch>& str)
|
|
||||||
{
|
|
||||||
return Key(str.data(), SizeType(str.size()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool EndObject(SizeType memberCount = 0) {
|
|
||||||
(void)memberCount;
|
|
||||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
|
|
||||||
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); // currently inside an Array, not Object
|
|
||||||
RAPIDJSON_ASSERT(0 == level_stack_.template Top<Level>()->valueCount % 2); // Object has a Key without a Value
|
|
||||||
level_stack_.template Pop<Level>(1);
|
|
||||||
return EndValue(WriteEndObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartArray() {
|
|
||||||
Prefix(kArrayType);
|
|
||||||
new (level_stack_.template Push<Level>()) Level(true);
|
|
||||||
return WriteStartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EndArray(SizeType elementCount = 0) {
|
|
||||||
(void)elementCount;
|
|
||||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
|
|
||||||
RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
|
|
||||||
level_stack_.template Pop<Level>(1);
|
|
||||||
return EndValue(WriteEndArray());
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/*! @name Convenience extensions */
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! Simpler but slower overload.
|
|
||||||
bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); }
|
|
||||||
bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); }
|
|
||||||
|
|
||||||
//@}
|
|
||||||
|
|
||||||
//! Write a raw JSON value.
|
|
||||||
/*!
|
|
||||||
For user to write a stringified JSON as a value.
|
|
||||||
|
|
||||||
\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
|
|
||||||
\param length Length of the json.
|
|
||||||
\param type Type of the root of json.
|
|
||||||
*/
|
|
||||||
bool RawValue(const Ch* json, size_t length, Type type) {
|
|
||||||
RAPIDJSON_ASSERT(json != 0);
|
|
||||||
Prefix(type);
|
|
||||||
return EndValue(WriteRawValue(json, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Flush the output stream.
|
|
||||||
/*!
|
|
||||||
Allows the user to flush the output stream immediately.
|
|
||||||
*/
|
|
||||||
void Flush() {
|
|
||||||
os_->Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const size_t kDefaultLevelDepth = 32;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
//! Information for each nested level
|
|
||||||
struct Level {
|
|
||||||
Level(bool inArray_) : valueCount(0), inArray(inArray_) {}
|
|
||||||
size_t valueCount; //!< number of values in this level
|
|
||||||
bool inArray; //!< true if in array, otherwise in object
|
|
||||||
};
|
|
||||||
|
|
||||||
bool WriteNull() {
|
|
||||||
PutReserve(*os_, 4);
|
|
||||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteBool(bool b) {
|
|
||||||
if (b) {
|
|
||||||
PutReserve(*os_, 4);
|
|
||||||
PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PutReserve(*os_, 5);
|
|
||||||
PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteInt(int i) {
|
|
||||||
char buffer[11];
|
|
||||||
const char* end = internal::i32toa(i, buffer);
|
|
||||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
|
||||||
for (const char* p = buffer; p != end; ++p)
|
|
||||||
PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteUint(unsigned u) {
|
|
||||||
char buffer[10];
|
|
||||||
const char* end = internal::u32toa(u, buffer);
|
|
||||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
|
||||||
for (const char* p = buffer; p != end; ++p)
|
|
||||||
PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteInt64(int64_t i64) {
|
|
||||||
char buffer[21];
|
|
||||||
const char* end = internal::i64toa(i64, buffer);
|
|
||||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
|
||||||
for (const char* p = buffer; p != end; ++p)
|
|
||||||
PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteUint64(uint64_t u64) {
|
|
||||||
char buffer[20];
|
|
||||||
char* end = internal::u64toa(u64, buffer);
|
|
||||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
|
||||||
for (char* p = buffer; p != end; ++p)
|
|
||||||
PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteDouble(double d) {
|
|
||||||
if (internal::Double(d).IsNanOrInf()) {
|
|
||||||
if (!(writeFlags & kWriteNanAndInfFlag))
|
|
||||||
return false;
|
|
||||||
if (internal::Double(d).IsNan()) {
|
|
||||||
PutReserve(*os_, 3);
|
|
||||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (internal::Double(d).Sign()) {
|
|
||||||
PutReserve(*os_, 9);
|
|
||||||
PutUnsafe(*os_, '-');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PutReserve(*os_, 8);
|
|
||||||
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
|
|
||||||
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[25];
|
|
||||||
char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
|
|
||||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
|
||||||
for (char* p = buffer; p != end; ++p)
|
|
||||||
PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteString(const Ch* str, SizeType length) {
|
|
||||||
static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
|
||||||
static const char escape[256] = {
|
|
||||||
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
||||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
||||||
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
|
|
||||||
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
|
|
||||||
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
|
|
||||||
Z16, Z16, // 30~4F
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
|
|
||||||
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
|
|
||||||
#undef Z16
|
|
||||||
};
|
|
||||||
|
|
||||||
if (TargetEncoding::supportUnicode)
|
|
||||||
PutReserve(*os_, 2 + length * 6); // "\uxxxx..."
|
|
||||||
else
|
|
||||||
PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..."
|
|
||||||
|
|
||||||
PutUnsafe(*os_, '\"');
|
|
||||||
GenericStringStream<SourceEncoding> is(str);
|
|
||||||
while (ScanWriteUnescapedString(is, length)) {
|
|
||||||
const Ch c = is.Peek();
|
|
||||||
if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
|
|
||||||
// Unicode escaping
|
|
||||||
unsigned codepoint;
|
|
||||||
if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))
|
|
||||||
return false;
|
|
||||||
PutUnsafe(*os_, '\\');
|
|
||||||
PutUnsafe(*os_, 'u');
|
|
||||||
if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
|
|
||||||
PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
|
|
||||||
// Surrogate pair
|
|
||||||
unsigned s = codepoint - 0x010000;
|
|
||||||
unsigned lead = (s >> 10) + 0xD800;
|
|
||||||
unsigned trail = (s & 0x3FF) + 0xDC00;
|
|
||||||
PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(lead ) & 15]);
|
|
||||||
PutUnsafe(*os_, '\\');
|
|
||||||
PutUnsafe(*os_, 'u');
|
|
||||||
PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
|
|
||||||
PutUnsafe(*os_, hexDigits[(trail ) & 15]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)])) {
|
|
||||||
is.Take();
|
|
||||||
PutUnsafe(*os_, '\\');
|
|
||||||
PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(escape[static_cast<unsigned char>(c)]));
|
|
||||||
if (escape[static_cast<unsigned char>(c)] == 'u') {
|
|
||||||
PutUnsafe(*os_, '0');
|
|
||||||
PutUnsafe(*os_, '0');
|
|
||||||
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);
|
|
||||||
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
|
|
||||||
Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
|
|
||||||
Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PutUnsafe(*os_, '\"');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) {
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteStartObject() { os_->Put('{'); return true; }
|
|
||||||
bool WriteEndObject() { os_->Put('}'); return true; }
|
|
||||||
bool WriteStartArray() { os_->Put('['); return true; }
|
|
||||||
bool WriteEndArray() { os_->Put(']'); return true; }
|
|
||||||
|
|
||||||
bool WriteRawValue(const Ch* json, size_t length) {
|
|
||||||
PutReserve(*os_, length);
|
|
||||||
GenericStringStream<SourceEncoding> is(json);
|
|
||||||
while (RAPIDJSON_LIKELY(is.Tell() < length)) {
|
|
||||||
RAPIDJSON_ASSERT(is.Peek() != '\0');
|
|
||||||
if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
|
|
||||||
Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
|
|
||||||
Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Prefix(Type type) {
|
|
||||||
(void)type;
|
|
||||||
if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
|
|
||||||
Level* level = level_stack_.template Top<Level>();
|
|
||||||
if (level->valueCount > 0) {
|
|
||||||
if (level->inArray)
|
|
||||||
os_->Put(','); // add comma if it is not the first element in array
|
|
||||||
else // in object
|
|
||||||
os_->Put((level->valueCount % 2 == 0) ? ',' : ':');
|
|
||||||
}
|
|
||||||
if (!level->inArray && level->valueCount % 2 == 0)
|
|
||||||
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
|
|
||||||
level->valueCount++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root.
|
|
||||||
hasRoot_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush the value if it is the top level one.
|
|
||||||
bool EndValue(bool ret) {
|
|
||||||
if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text
|
|
||||||
Flush();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputStream* os_;
|
|
||||||
internal::Stack<StackAllocator> level_stack_;
|
|
||||||
int maxDecimalPlaces_;
|
|
||||||
bool hasRoot_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
|
||||||
Writer(const Writer&);
|
|
||||||
Writer& operator=(const Writer&);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Full specialization for StringStream to prevent memory copying
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::WriteInt(int i) {
|
|
||||||
char *buffer = os_->Push(11);
|
|
||||||
const char* end = internal::i32toa(i, buffer);
|
|
||||||
os_->Pop(static_cast<size_t>(11 - (end - buffer)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
|
|
||||||
char *buffer = os_->Push(10);
|
|
||||||
const char* end = internal::u32toa(u, buffer);
|
|
||||||
os_->Pop(static_cast<size_t>(10 - (end - buffer)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
|
|
||||||
char *buffer = os_->Push(21);
|
|
||||||
const char* end = internal::i64toa(i64, buffer);
|
|
||||||
os_->Pop(static_cast<size_t>(21 - (end - buffer)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
|
|
||||||
char *buffer = os_->Push(20);
|
|
||||||
const char* end = internal::u64toa(u, buffer);
|
|
||||||
os_->Pop(static_cast<size_t>(20 - (end - buffer)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
|
||||||
if (internal::Double(d).IsNanOrInf()) {
|
|
||||||
// Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
|
|
||||||
if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
|
|
||||||
return false;
|
|
||||||
if (internal::Double(d).IsNan()) {
|
|
||||||
PutReserve(*os_, 3);
|
|
||||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (internal::Double(d).Sign()) {
|
|
||||||
PutReserve(*os_, 9);
|
|
||||||
PutUnsafe(*os_, '-');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PutReserve(*os_, 8);
|
|
||||||
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
|
|
||||||
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *buffer = os_->Push(25);
|
|
||||||
char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
|
|
||||||
os_->Pop(static_cast<size_t>(25 - (end - buffer)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {
|
|
||||||
if (length < 16)
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
|
|
||||||
if (!RAPIDJSON_LIKELY(is.Tell() < length))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char* p = is.src_;
|
|
||||||
const char* end = is.head_ + length;
|
|
||||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
|
||||||
const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));
|
|
||||||
if (nextAligned > end)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
while (p != nextAligned)
|
|
||||||
if (*p < 0x20 || *p == '\"' || *p == '\\') {
|
|
||||||
is.src_ = p;
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
os_->PutUnsafe(*p++);
|
|
||||||
|
|
||||||
// The rest of string using SIMD
|
|
||||||
static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
|
|
||||||
static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
|
|
||||||
static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
|
|
||||||
const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
|
|
||||||
const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
|
|
||||||
const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
|
|
||||||
|
|
||||||
for (; p != endAligned; p += 16) {
|
|
||||||
const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
|
|
||||||
const __m128i t1 = _mm_cmpeq_epi8(s, dq);
|
|
||||||
const __m128i t2 = _mm_cmpeq_epi8(s, bs);
|
|
||||||
const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
|
|
||||||
const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
|
|
||||||
unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
|
|
||||||
if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
|
|
||||||
SizeType len;
|
|
||||||
#ifdef _MSC_VER // Find the index of first escaped
|
|
||||||
unsigned long offset;
|
|
||||||
_BitScanForward(&offset, r);
|
|
||||||
len = offset;
|
|
||||||
#else
|
|
||||||
len = static_cast<SizeType>(__builtin_ffs(r) - 1);
|
|
||||||
#endif
|
|
||||||
char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
q[i] = p[i];
|
|
||||||
|
|
||||||
p += len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s);
|
|
||||||
}
|
|
||||||
|
|
||||||
is.src_ = p;
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
}
|
|
||||||
#elif defined(RAPIDJSON_NEON)
|
|
||||||
template<>
|
|
||||||
inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {
|
|
||||||
if (length < 16)
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
|
|
||||||
if (!RAPIDJSON_LIKELY(is.Tell() < length))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char* p = is.src_;
|
|
||||||
const char* end = is.head_ + length;
|
|
||||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
|
||||||
const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));
|
|
||||||
if (nextAligned > end)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
while (p != nextAligned)
|
|
||||||
if (*p < 0x20 || *p == '\"' || *p == '\\') {
|
|
||||||
is.src_ = p;
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
os_->PutUnsafe(*p++);
|
|
||||||
|
|
||||||
// The rest of string using SIMD
|
|
||||||
const uint8x16_t s0 = vmovq_n_u8('"');
|
|
||||||
const uint8x16_t s1 = vmovq_n_u8('\\');
|
|
||||||
const uint8x16_t s2 = vmovq_n_u8('\b');
|
|
||||||
const uint8x16_t s3 = vmovq_n_u8(32);
|
|
||||||
|
|
||||||
for (; p != endAligned; p += 16) {
|
|
||||||
const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
|
|
||||||
uint8x16_t x = vceqq_u8(s, s0);
|
|
||||||
x = vorrq_u8(x, vceqq_u8(s, s1));
|
|
||||||
x = vorrq_u8(x, vceqq_u8(s, s2));
|
|
||||||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
|
||||||
|
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
|
||||||
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
|
||||||
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
|
||||||
|
|
||||||
SizeType len = 0;
|
|
||||||
bool escaped = false;
|
|
||||||
if (low == 0) {
|
|
||||||
if (high != 0) {
|
|
||||||
uint32_t lz = internal::clzll(high);
|
|
||||||
len = 8 + (lz >> 3);
|
|
||||||
escaped = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uint32_t lz = internal::clzll(low);
|
|
||||||
len = lz >> 3;
|
|
||||||
escaped = true;
|
|
||||||
}
|
|
||||||
if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
|
|
||||||
char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
q[i] = p[i];
|
|
||||||
|
|
||||||
p += len;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
vst1q_u8(reinterpret_cast<uint8_t *>(os_->PushUnsafe(16)), s);
|
|
||||||
}
|
|
||||||
|
|
||||||
is.src_ = p;
|
|
||||||
return RAPIDJSON_LIKELY(is.Tell() < length);
|
|
||||||
}
|
|
||||||
#endif // RAPIDJSON_NEON
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__clang__)
|
|
||||||
RAPIDJSON_DIAG_POP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
|
525
vendor/github.com/Benau/go_rlottie/rlottie.h
generated
vendored
525
vendor/github.com/Benau/go_rlottie/rlottie.h
generated
vendored
@ -1,525 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _RLOTTIE_H_
|
|
||||||
#define _RLOTTIE_H_
|
|
||||||
|
|
||||||
#include <future>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
|
||||||
#ifdef RLOTTIE_BUILD
|
|
||||||
#define RLOTTIE_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define RLOTTIE_API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef RLOTTIE_BUILD
|
|
||||||
#define RLOTTIE_API __attribute__ ((visibility ("default")))
|
|
||||||
#else
|
|
||||||
#define RLOTTIE_API
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class AnimationImpl;
|
|
||||||
struct LOTNode;
|
|
||||||
struct LOTLayerNode;
|
|
||||||
|
|
||||||
namespace rlottie {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configures rlottie model cache policy.
|
|
||||||
*
|
|
||||||
* Provides Library level control to configure model cache
|
|
||||||
* policy. Setting it to 0 will disable
|
|
||||||
* the cache as well as flush all the previously cached content.
|
|
||||||
*
|
|
||||||
* @param[in] cacheSize Maximum Model Cache size.
|
|
||||||
*
|
|
||||||
* @note to disable Caching configure with 0 size.
|
|
||||||
* @note to flush the current Cache content configure it with 0 and
|
|
||||||
* then reconfigure with the new size.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API void configureModelCacheSize(size_t cacheSize);
|
|
||||||
|
|
||||||
struct Color {
|
|
||||||
Color() = default;
|
|
||||||
Color(float r, float g , float b):_r(r), _g(g), _b(b){}
|
|
||||||
float r() const {return _r;}
|
|
||||||
float g() const {return _g;}
|
|
||||||
float b() const {return _b;}
|
|
||||||
private:
|
|
||||||
float _r{0};
|
|
||||||
float _g{0};
|
|
||||||
float _b{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Size {
|
|
||||||
Size() = default;
|
|
||||||
Size(float w, float h):_w(w), _h(h){}
|
|
||||||
float w() const {return _w;}
|
|
||||||
float h() const {return _h;}
|
|
||||||
private:
|
|
||||||
float _w{0};
|
|
||||||
float _h{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Point {
|
|
||||||
Point() = default;
|
|
||||||
Point(float x, float y):_x(x), _y(y){}
|
|
||||||
float x() const {return _x;}
|
|
||||||
float y() const {return _y;}
|
|
||||||
private:
|
|
||||||
float _x{0};
|
|
||||||
float _y{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FrameInfo {
|
|
||||||
explicit FrameInfo(uint32_t frame): _frameNo(frame){}
|
|
||||||
uint32_t curFrame() const {return _frameNo;}
|
|
||||||
private:
|
|
||||||
uint32_t _frameNo;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Property {
|
|
||||||
FillColor, /*!< Color property of Fill object , value type is rlottie::Color */
|
|
||||||
FillOpacity, /*!< Opacity property of Fill object , value type is float [ 0 .. 100] */
|
|
||||||
StrokeColor, /*!< Color property of Stroke object , value type is rlottie::Color */
|
|
||||||
StrokeOpacity, /*!< Opacity property of Stroke object , value type is float [ 0 .. 100] */
|
|
||||||
StrokeWidth, /*!< stroke width property of Stroke object , value type is float */
|
|
||||||
TrAnchor, /*!< Transform Anchor property of Layer and Group object , value type is rlottie::Point */
|
|
||||||
TrPosition, /*!< Transform Position property of Layer and Group object , value type is rlottie::Point */
|
|
||||||
TrScale, /*!< Transform Scale property of Layer and Group object , value type is rlottie::Size. range[0 ..100] */
|
|
||||||
TrRotation, /*!< Transform Rotation property of Layer and Group object , value type is float. range[0 .. 360] in degrees*/
|
|
||||||
TrOpacity /*!< Transform Opacity property of Layer and Group object , value type is float [ 0 .. 100] */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Color_Type{};
|
|
||||||
struct Point_Type{};
|
|
||||||
struct Size_Type{};
|
|
||||||
struct Float_Type{};
|
|
||||||
template <typename T> struct MapType;
|
|
||||||
|
|
||||||
class RLOTTIE_API Surface {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Surface object constructor.
|
|
||||||
*
|
|
||||||
* @param[in] buffer surface buffer.
|
|
||||||
* @param[in] width surface width.
|
|
||||||
* @param[in] height surface height.
|
|
||||||
* @param[in] bytesPerLine number of bytes in a surface scanline.
|
|
||||||
*
|
|
||||||
* @note Default surface format is ARGB32_Premultiplied.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
Surface(uint32_t *buffer, size_t width, size_t height, size_t bytesPerLine);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets the Draw Area available on the Surface.
|
|
||||||
*
|
|
||||||
* Lottie will use the draw region size to generate frame image
|
|
||||||
* and will update only the draw rgion of the surface.
|
|
||||||
*
|
|
||||||
* @param[in] x region area x position.
|
|
||||||
* @param[in] y region area y position.
|
|
||||||
* @param[in] width region area width.
|
|
||||||
* @param[in] height region area height.
|
|
||||||
*
|
|
||||||
* @note Default surface format is ARGB32_Premultiplied.
|
|
||||||
* @note Default draw region area is [ 0 , 0, surface width , surface height]
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
void setDrawRegion(size_t x, size_t y, size_t width, size_t height);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns width of the surface.
|
|
||||||
*
|
|
||||||
* @return surface width
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
size_t width() const {return mWidth;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns height of the surface.
|
|
||||||
*
|
|
||||||
* @return surface height
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t height() const {return mHeight;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns number of bytes in the surface scanline.
|
|
||||||
*
|
|
||||||
* @return number of bytes in scanline.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t bytesPerLine() const {return mBytesPerLine;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns buffer attached tp the surface.
|
|
||||||
*
|
|
||||||
* @return buffer attaced to the Surface.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
uint32_t *buffer() const {return mBuffer;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns drawable area width of the surface.
|
|
||||||
*
|
|
||||||
* @return drawable area width
|
|
||||||
*
|
|
||||||
* @note Default value is width() of the surface
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
size_t drawRegionWidth() const {return mDrawArea.w;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns drawable area height of the surface.
|
|
||||||
*
|
|
||||||
* @return drawable area height
|
|
||||||
*
|
|
||||||
* @note Default value is height() of the surface
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t drawRegionHeight() const {return mDrawArea.h;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns drawable area's x position of the surface.
|
|
||||||
*
|
|
||||||
* @return drawable area's x potition.
|
|
||||||
*
|
|
||||||
* @note Default value is 0
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t drawRegionPosX() const {return mDrawArea.x;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns drawable area's y position of the surface.
|
|
||||||
*
|
|
||||||
* @return drawable area's y potition.
|
|
||||||
*
|
|
||||||
* @note Default value is 0
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t drawRegionPosY() const {return mDrawArea.y;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Default constructor.
|
|
||||||
*/
|
|
||||||
Surface() = default;
|
|
||||||
private:
|
|
||||||
uint32_t *mBuffer{nullptr};
|
|
||||||
size_t mWidth{0};
|
|
||||||
size_t mHeight{0};
|
|
||||||
size_t mBytesPerLine{0};
|
|
||||||
struct {
|
|
||||||
size_t x{0};
|
|
||||||
size_t y{0};
|
|
||||||
size_t w{0};
|
|
||||||
size_t h{0};
|
|
||||||
}mDrawArea;
|
|
||||||
};
|
|
||||||
|
|
||||||
using MarkerList = std::vector<std::tuple<std::string, int , int>>;
|
|
||||||
/**
|
|
||||||
* @brief https://helpx.adobe.com/after-effects/using/layer-markers-composition-markers.html
|
|
||||||
* Markers exported form AE are used to describe a segmnet of an animation {comment/tag , startFrame, endFrame}
|
|
||||||
* Marker can be use to devide a resource in to separate animations by tagging the segment with comment string ,
|
|
||||||
* start frame and duration of that segment.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using LayerInfoList = std::vector<std::tuple<std::string, int , int>>;
|
|
||||||
|
|
||||||
|
|
||||||
using ColorFilter = std::function<void(float &r , float &g, float &b)>;
|
|
||||||
|
|
||||||
class RLOTTIE_API Animation {
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructs an animation object from file path.
|
|
||||||
*
|
|
||||||
* @param[in] path Lottie resource file path
|
|
||||||
* @param[in] cachePolicy whether to cache or not the model data.
|
|
||||||
* use only when need to explicit disabl caching for a
|
|
||||||
* particular resource. To disable caching at library level
|
|
||||||
* use @see configureModelCacheSize() instead.
|
|
||||||
*
|
|
||||||
* @return Animation object that can render the contents of the
|
|
||||||
* Lottie resource represented by file path.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static std::unique_ptr<Animation>
|
|
||||||
loadFromFile(const std::string &path, bool cachePolicy=true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructs an animation object from JSON string data.
|
|
||||||
*
|
|
||||||
* @param[in] jsonData The JSON string data.
|
|
||||||
* @param[in] key the string that will be used to cache the JSON string data.
|
|
||||||
* @param[in] resourcePath the path will be used to search for external resource.
|
|
||||||
* @param[in] cachePolicy whether to cache or not the model data.
|
|
||||||
* use only when need to explicit disabl caching for a
|
|
||||||
* particular resource. To disable caching at library level
|
|
||||||
* use @see configureModelCacheSize() instead.
|
|
||||||
*
|
|
||||||
* @return Animation object that can render the contents of the
|
|
||||||
* Lottie resource represented by JSON string data.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static std::unique_ptr<Animation>
|
|
||||||
loadFromData(std::string jsonData, const std::string &key,
|
|
||||||
const std::string &resourcePath="", bool cachePolicy=true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructs an animation object from JSON string data and update.
|
|
||||||
* the color properties using ColorFilter.
|
|
||||||
|
|
||||||
* @param[in] jsonData The JSON string data.
|
|
||||||
* @param[in] resourcePath the path will be used to search for external resource.
|
|
||||||
* @param[in] filter The color filter that will be applied for each color property
|
|
||||||
* found during parsing.
|
|
||||||
|
|
||||||
* @return Animation object that can render the contents of the
|
|
||||||
* Lottie resource represented by JSON string data.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static std::unique_ptr<Animation>
|
|
||||||
loadFromData(std::string jsonData, std::string resourcePath, ColorFilter filter);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns default framerate of the Lottie resource.
|
|
||||||
*
|
|
||||||
* @return framerate of the Lottie resource
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
double frameRate() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns total number of frames present in the Lottie resource.
|
|
||||||
*
|
|
||||||
* @return frame count of the Lottie resource.
|
|
||||||
*
|
|
||||||
* @note frame number starts with 0.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t totalFrame() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns default viewport size of the Lottie resource.
|
|
||||||
*
|
|
||||||
* @param[out] width default width of the viewport.
|
|
||||||
* @param[out] height default height of the viewport.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void size(size_t &width, size_t &height) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns total animation duration of Lottie resource in second.
|
|
||||||
* it uses totalFrame() and frameRate() to calculate the duration.
|
|
||||||
* duration = totalFrame() / frameRate().
|
|
||||||
*
|
|
||||||
* @return total animation duration in second.
|
|
||||||
* @retval 0 if the Lottie resource has no animation.
|
|
||||||
*
|
|
||||||
* @see totalFrame()
|
|
||||||
* @see frameRate()
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
double duration() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns frame number for a given position.
|
|
||||||
* this function helps to map the position value retuned
|
|
||||||
* by the animator to a frame number in side the Lottie resource.
|
|
||||||
* frame_number = lerp(start_frame, endframe, pos);
|
|
||||||
*
|
|
||||||
* @param[in] pos normalized position value [0 ... 1]
|
|
||||||
*
|
|
||||||
* @return frame numer maps to the position value [startFrame .... endFrame]
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
size_t frameAtPos(double pos);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Renders the content to surface Asynchronously.
|
|
||||||
* it gives a future in return to get the result of the
|
|
||||||
* rendering at a future point.
|
|
||||||
* To get best performance user has to start rendering as soon as
|
|
||||||
* it finds that content at {frameNo} has to be rendered and get the
|
|
||||||
* result from the future at the last moment when the surface is needed
|
|
||||||
* to draw into the screen.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param[in] frameNo Content corresponds to the @p frameNo needs to be drawn
|
|
||||||
* @param[in] surface Surface in which content will be drawn
|
|
||||||
* @param[in] keepAspectRatio whether to keep the aspect ratio while scaling the content.
|
|
||||||
*
|
|
||||||
* @return future that will hold the result when rendering finished.
|
|
||||||
*
|
|
||||||
* for Synchronus rendering @see renderSync
|
|
||||||
*
|
|
||||||
* @see Surface
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
std::future<Surface> render(size_t frameNo, Surface surface, bool keepAspectRatio=true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Renders the content to surface synchronously.
|
|
||||||
* for performance use the async rendering @see render
|
|
||||||
*
|
|
||||||
* @param[in] frameNo Content corresponds to the @p frameNo needs to be drawn
|
|
||||||
* @param[in] surface Surface in which content will be drawn
|
|
||||||
* @param[in] keepAspectRatio whether to keep the aspect ratio while scaling the content.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
void renderSync(size_t frameNo, Surface surface, bool keepAspectRatio=true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns root layer of the composition updated with
|
|
||||||
* content of the Lottie resource at frame number @p frameNo.
|
|
||||||
*
|
|
||||||
* @param[in] frameNo Content corresponds to the @p frameNo needs to be extracted.
|
|
||||||
* @param[in] width content viewbox width
|
|
||||||
* @param[in] height content viewbox height
|
|
||||||
*
|
|
||||||
* @return Root layer node.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
const LOTLayerNode * renderTree(size_t frameNo, size_t width, size_t height) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns Composition Markers.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return returns MarkerList of the Composition.
|
|
||||||
*
|
|
||||||
* @see MarkerList
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
const MarkerList& markers() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns Layer information{name, inFrame, outFrame} of all the child layers of the composition.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return List of Layer Information of the Composition.
|
|
||||||
*
|
|
||||||
* @see LayerInfoList
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
const LayerInfoList& layers() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets property value for the specified {@link KeyPath}. This {@link KeyPath} can resolve
|
|
||||||
* to multiple contents. In that case, the callback's value will apply to all of them.
|
|
||||||
*
|
|
||||||
* Keypath should conatin object names separated by (.) and can handle globe(**) or wildchar(*).
|
|
||||||
*
|
|
||||||
* @usage
|
|
||||||
* To change fillcolor property of fill1 object in the layer1->group1->fill1 hirarchy to RED color
|
|
||||||
*
|
|
||||||
* player->setValue<rlottie::Property::FillColor>("layer1.group1.fill1", rlottie::Color(1, 0, 0);
|
|
||||||
*
|
|
||||||
* if all the color property inside group1 needs to be changed to GREEN color
|
|
||||||
*
|
|
||||||
* player->setValue<rlottie::Property::FillColor>("**.group1.**", rlottie::Color(0, 1, 0);
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
template<Property prop, typename AnyValue>
|
|
||||||
void setValue(const std::string &keypath, AnyValue value)
|
|
||||||
{
|
|
||||||
setValue(MapType<std::integral_constant<Property, prop>>{}, prop, keypath, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief default destructor
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
~Animation();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setValue(Color_Type, Property, const std::string &, Color);
|
|
||||||
void setValue(Float_Type, Property, const std::string &, float);
|
|
||||||
void setValue(Size_Type, Property, const std::string &, Size);
|
|
||||||
void setValue(Point_Type, Property, const std::string &, Point);
|
|
||||||
|
|
||||||
void setValue(Color_Type, Property, const std::string &, std::function<Color(const FrameInfo &)> &&);
|
|
||||||
void setValue(Float_Type, Property, const std::string &, std::function<float(const FrameInfo &)> &&);
|
|
||||||
void setValue(Size_Type, Property, const std::string &, std::function<Size(const FrameInfo &)> &&);
|
|
||||||
void setValue(Point_Type, Property, const std::string &, std::function<Point(const FrameInfo &)> &&);
|
|
||||||
/**
|
|
||||||
* @brief default constructor
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
Animation();
|
|
||||||
|
|
||||||
std::unique_ptr<AnimationImpl> d;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Map Property to Value type
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::FillColor>>: Color_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::StrokeColor>>: Color_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::FillOpacity>>: Float_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::StrokeOpacity>>: Float_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::StrokeWidth>>: Float_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::TrRotation>>: Float_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::TrOpacity>>: Float_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::TrAnchor>>: Point_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::TrPosition>>: Point_Type{};
|
|
||||||
template<> struct MapType<std::integral_constant<Property, Property::TrScale>>: Size_Type{};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace lotplayer
|
|
||||||
|
|
||||||
#endif // _RLOTTIE_H_
|
|
299
vendor/github.com/Benau/go_rlottie/rlottie_capi.h
generated
vendored
299
vendor/github.com/Benau/go_rlottie/rlottie_capi.h
generated
vendored
@ -1,299 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _RLOTTIE_CAPI_H_
|
|
||||||
#define _RLOTTIE_CAPI_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "rlottiecommon.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_FILLCOLOR, /*!< Color property of Fill object , value type is float [0 ... 1] */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_FILLOPACITY, /*!< Opacity property of Fill object , value type is float [ 0 .. 100] */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_STROKECOLOR, /*!< Color property of Stroke object , value type is float [0 ... 1] */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_STROKEOPACITY, /*!< Opacity property of Stroke object , value type is float [ 0 .. 100] */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_STROKEWIDTH, /*!< stroke with property of Stroke object , value type is float */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_TR_ANCHOR, /*!< Transform Anchor property of Layer and Group object , value type is int */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_TR_POSITION, /*!< Transform Position property of Layer and Group object , value type is int */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_TR_SCALE, /*!< Transform Scale property of Layer and Group object , value type is float range[0 ..100] */
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_TR_ROTATION, /*!< Transform Scale property of Layer and Group object , value type is float. range[0 .. 360] in degrees*/
|
|
||||||
LOTTIE_ANIMATION_PROPERTY_TR_OPACITY /*!< Transform Opacity property of Layer and Group object , value type is float [ 0 .. 100] */
|
|
||||||
}Lottie_Animation_Property;
|
|
||||||
|
|
||||||
typedef struct Lottie_Animation_S Lottie_Animation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructs an animation object from file path.
|
|
||||||
*
|
|
||||||
* @param[in] path Lottie resource file path
|
|
||||||
*
|
|
||||||
* @return Animation object that can build the contents of the
|
|
||||||
* Lottie resource represented by file path.
|
|
||||||
*
|
|
||||||
* @see lottie_animation_destroy()
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API Lottie_Animation *lottie_animation_from_file(const char *path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructs an animation object from JSON string data.
|
|
||||||
*
|
|
||||||
* @param[in] data The JSON string data.
|
|
||||||
* @param[in] key the string that will be used to cache the JSON string data.
|
|
||||||
* @param[in] resource_path the path that will be used to load external resource needed by the JSON data.
|
|
||||||
*
|
|
||||||
* @return Animation object that can build the contents of the
|
|
||||||
* Lottie resource represented by JSON string data.
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API Lottie_Animation *lottie_animation_from_data(const char *data, const char *key, const char *resource_path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Free given Animation object resource.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object to free.
|
|
||||||
*
|
|
||||||
* @see lottie_animation_from_file()
|
|
||||||
* @see lottie_animation_from_data()
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API void lottie_animation_destroy(Lottie_Animation *animation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns default viewport size of the Lottie resource.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
* @param[out] w default width of the viewport.
|
|
||||||
* @param[out] h default height of the viewport.
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API void lottie_animation_get_size(const Lottie_Animation *animation, size_t *width, size_t *height);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns total animation duration of Lottie resource in second.
|
|
||||||
* it uses totalFrame() and frameRate() to calculate the duration.
|
|
||||||
* duration = totalFrame() / frameRate().
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
*
|
|
||||||
* @return total animation duration in second.
|
|
||||||
* @c 0 if the Lottie resource has no animation.
|
|
||||||
*
|
|
||||||
* @see lottie_animation_get_totalframe()
|
|
||||||
* @see lottie_animation_get_framerate()
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API double lottie_animation_get_duration(const Lottie_Animation *animation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns total number of frames present in the Lottie resource.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
*
|
|
||||||
* @return frame count of the Lottie resource.*
|
|
||||||
*
|
|
||||||
* @note frame number starts with 0.
|
|
||||||
*
|
|
||||||
* @see lottie_animation_get_duration()
|
|
||||||
* @see lottie_animation_get_framerate()
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API size_t lottie_animation_get_totalframe(const Lottie_Animation *animation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns default framerate of the Lottie resource.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
*
|
|
||||||
* @return framerate of the Lottie resource
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
RLOTTIE_API double lottie_animation_get_framerate(const Lottie_Animation *animation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the render tree which contains the snapshot of the animation object
|
|
||||||
* at frame = @c frame_num, the content of the animation in that frame number.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
* @param[in] frame_num Content corresponds to the @p frame_num needs to be drawn
|
|
||||||
* @param[in] width requested snapshot viewport width.
|
|
||||||
* @param[in] height requested snapshot viewport height.
|
|
||||||
*
|
|
||||||
* @return Animation snapshot tree.
|
|
||||||
*
|
|
||||||
* @note: User has to traverse the tree for rendering.
|
|
||||||
*
|
|
||||||
* @see LOTLayerNode
|
|
||||||
* @see LOTNode
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API const LOTLayerNode *lottie_animation_render_tree(Lottie_Animation *animation, size_t frame_num, size_t width, size_t height);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maps position to frame number and returns it.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
* @param[in] pos position in the range [ 0.0 .. 1.0 ].
|
|
||||||
*
|
|
||||||
* @return mapped frame numbe in the range [ start_frame .. end_frame ].
|
|
||||||
* @c 0 if the Lottie resource has no animation.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API size_t lottie_animation_get_frame_at_pos(const Lottie_Animation *animation, float pos);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Request to render the content of the frame @p frame_num to buffer @p buffer.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
* @param[in] frame_num the frame number needs to be rendered.
|
|
||||||
* @param[in] buffer surface buffer use for rendering.
|
|
||||||
* @param[in] width width of the surface
|
|
||||||
* @param[in] height height of the surface
|
|
||||||
* @param[in] bytes_per_line stride of the surface in bytes.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API void lottie_animation_render(Lottie_Animation *animation, size_t frame_num, uint32_t *buffer, size_t width, size_t height, size_t bytes_per_line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Request to render the content of the frame @p frame_num to buffer @p buffer asynchronously.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
* @param[in] frame_num the frame number needs to be rendered.
|
|
||||||
* @param[in] buffer surface buffer use for rendering.
|
|
||||||
* @param[in] width width of the surface
|
|
||||||
* @param[in] height height of the surface
|
|
||||||
* @param[in] bytes_per_line stride of the surface in bytes.
|
|
||||||
*
|
|
||||||
* @note user must call lottie_animation_render_flush() to make sure render is finished.
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API void lottie_animation_render_async(Lottie_Animation *animation, size_t frame_num, uint32_t *buffer, size_t width, size_t height, size_t bytes_per_line);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Request to finish the current async renderer job for this animation object.
|
|
||||||
* If render is finished then this call returns immidiately.
|
|
||||||
* If not, it waits till render job finish and then return.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
*
|
|
||||||
* @warning User must call lottie_animation_render_async() and lottie_animation_render_flush()
|
|
||||||
* in pair to get the benefit of async rendering.
|
|
||||||
*
|
|
||||||
* @return the pixel buffer it finished rendering.
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API uint32_t *lottie_animation_render_flush(Lottie_Animation *animation);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Request to change the properties of this animation object.
|
|
||||||
* Keypath should conatin object names separated by (.) and can handle globe(**) or wildchar(*)
|
|
||||||
*
|
|
||||||
* @usage
|
|
||||||
* To change fillcolor property of fill1 object in the layer1->group1->fill1 hirarchy to RED color
|
|
||||||
*
|
|
||||||
* lottie_animation_property_override(animation, LOTTIE_ANIMATION_PROPERTY_FILLCOLOR, "layer1.group1.fill1", 1.0, 0.0, 0.0);
|
|
||||||
*
|
|
||||||
* if all the color property inside group1 needs to be changed to GREEN color
|
|
||||||
*
|
|
||||||
* lottie_animation_property_override(animation, LOTTIE_ANIMATION_PROPERTY_FILLCOLOR, "**.group1.**", 1.0, 0.0, 0.0);
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
* @param[in] type Property type. (@p Lottie_Animation_Property)
|
|
||||||
* @param[in] keypath Specific content of target.
|
|
||||||
* @param[in] ... Property values.
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
* */
|
|
||||||
RLOTTIE_API void lottie_animation_property_override(Lottie_Animation *animation, const Lottie_Animation_Property type, const char *keypath, ...);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns list of markers in the Lottie resource
|
|
||||||
* @p LOTMarkerList has a @p LOTMarker list and size of list
|
|
||||||
* @p LOTMarker has the marker's name, start frame, and end frame.
|
|
||||||
*
|
|
||||||
* @param[in] animation Animation object.
|
|
||||||
*
|
|
||||||
* @return The list of marker. If there is no marker, return null.
|
|
||||||
*
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
* @internal
|
|
||||||
* */
|
|
||||||
RLOTTIE_API const LOTMarkerList* lottie_animation_get_markerlist(Lottie_Animation *animation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configures rlottie model cache policy.
|
|
||||||
*
|
|
||||||
* Provides Library level control to configure model cache
|
|
||||||
* policy. Setting it to 0 will disable
|
|
||||||
* the cache as well as flush all the previously cached content.
|
|
||||||
*
|
|
||||||
* @param[in] cacheSize Maximum Model Cache size.
|
|
||||||
*
|
|
||||||
* @note to disable Caching configure with 0 size.
|
|
||||||
* @note to flush the current Cache content configure it with 0 and
|
|
||||||
* then reconfigure with the new size.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
RLOTTIE_API void lottie_configure_model_cache_size(size_t cacheSize);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //_RLOTTIE_CAPI_H_
|
|
||||||
|
|
231
vendor/github.com/Benau/go_rlottie/rlottiecommon.h
generated
vendored
231
vendor/github.com/Benau/go_rlottie/rlottiecommon.h
generated
vendored
@ -1,231 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _RLOTTIE_COMMON_H_
|
|
||||||
#define _RLOTTIE_COMMON_H_
|
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
|
||||||
#ifdef RLOTTIE_BUILD
|
|
||||||
#define RLOTTIE_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define RLOTTIE_API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef RLOTTIE_BUILD
|
|
||||||
#define RLOTTIE_API __attribute__ ((visibility ("default")))
|
|
||||||
#else
|
|
||||||
#define RLOTTIE_API
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup Lottie_Animation Lottie_Animation
|
|
||||||
*
|
|
||||||
* Lottie Animation is a modern style vector based animation design. Its animation
|
|
||||||
* resource(within json format) could be generated by Adobe After Effect using
|
|
||||||
* bodymovin plugin. You can find a good examples in Lottie Community which
|
|
||||||
* shares many free resources(see: www.lottiefiles.com).
|
|
||||||
*
|
|
||||||
* This Lottie_Animation is a common engine to manipulate, control Lottie
|
|
||||||
* Animation from the Lottie resource - json file. It provides a scene-graph
|
|
||||||
* node tree per frames by user demand as well as rasterized frame images.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup Lottie_Animation
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BrushSolid = 0,
|
|
||||||
BrushGradient
|
|
||||||
} LOTBrushType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FillEvenOdd = 0,
|
|
||||||
FillWinding
|
|
||||||
} LOTFillRule;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
JoinMiter = 0,
|
|
||||||
JoinBevel,
|
|
||||||
JoinRound
|
|
||||||
} LOTJoinStyle;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
CapFlat = 0,
|
|
||||||
CapSquare,
|
|
||||||
CapRound
|
|
||||||
} LOTCapStyle;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
GradientLinear = 0,
|
|
||||||
GradientRadial
|
|
||||||
} LOTGradientType;
|
|
||||||
|
|
||||||
typedef struct LOTGradientStop
|
|
||||||
{
|
|
||||||
float pos;
|
|
||||||
unsigned char r, g, b, a;
|
|
||||||
} LOTGradientStop;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
MaskAdd = 0,
|
|
||||||
MaskSubstract,
|
|
||||||
MaskIntersect,
|
|
||||||
MaskDifference
|
|
||||||
} LOTMaskType;
|
|
||||||
|
|
||||||
typedef struct LOTMask {
|
|
||||||
struct {
|
|
||||||
const float *ptPtr;
|
|
||||||
size_t ptCount;
|
|
||||||
const char* elmPtr;
|
|
||||||
size_t elmCount;
|
|
||||||
} mPath;
|
|
||||||
LOTMaskType mMode;
|
|
||||||
unsigned char mAlpha;
|
|
||||||
}LOTMask;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
MatteNone = 0,
|
|
||||||
MatteAlpha,
|
|
||||||
MatteAlphaInv,
|
|
||||||
MatteLuma,
|
|
||||||
MatteLumaInv
|
|
||||||
} LOTMatteType;
|
|
||||||
|
|
||||||
typedef struct LOTMarker {
|
|
||||||
char *name;
|
|
||||||
size_t startframe;
|
|
||||||
size_t endframe;
|
|
||||||
} LOTMarker;
|
|
||||||
|
|
||||||
typedef struct LOTMarkerList {
|
|
||||||
LOTMarker *ptr;
|
|
||||||
size_t size;
|
|
||||||
} LOTMarkerList;
|
|
||||||
|
|
||||||
typedef struct LOTNode {
|
|
||||||
|
|
||||||
#define ChangeFlagNone 0x0000
|
|
||||||
#define ChangeFlagPath 0x0001
|
|
||||||
#define ChangeFlagPaint 0x0010
|
|
||||||
#define ChangeFlagAll (ChangeFlagPath & ChangeFlagPaint)
|
|
||||||
|
|
||||||
struct {
|
|
||||||
const float *ptPtr;
|
|
||||||
size_t ptCount;
|
|
||||||
const char *elmPtr;
|
|
||||||
size_t elmCount;
|
|
||||||
} mPath;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
unsigned char r, g, b, a;
|
|
||||||
} mColor;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
unsigned char enable;
|
|
||||||
float width;
|
|
||||||
LOTCapStyle cap;
|
|
||||||
LOTJoinStyle join;
|
|
||||||
float miterLimit;
|
|
||||||
float *dashArray;
|
|
||||||
int dashArraySize;
|
|
||||||
} mStroke;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
LOTGradientType type;
|
|
||||||
LOTGradientStop *stopPtr;
|
|
||||||
size_t stopCount;
|
|
||||||
struct {
|
|
||||||
float x, y;
|
|
||||||
} start, end, center, focal;
|
|
||||||
float cradius;
|
|
||||||
float fradius;
|
|
||||||
} mGradient;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
unsigned char *data;
|
|
||||||
size_t width;
|
|
||||||
size_t height;
|
|
||||||
unsigned char mAlpha;
|
|
||||||
struct {
|
|
||||||
float m11; float m12; float m13;
|
|
||||||
float m21; float m22; float m23;
|
|
||||||
float m31; float m32; float m33;
|
|
||||||
} mMatrix;
|
|
||||||
} mImageInfo;
|
|
||||||
|
|
||||||
int mFlag;
|
|
||||||
LOTBrushType mBrushType;
|
|
||||||
LOTFillRule mFillRule;
|
|
||||||
|
|
||||||
const char *keypath;
|
|
||||||
} LOTNode;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct LOTLayerNode {
|
|
||||||
|
|
||||||
struct {
|
|
||||||
LOTMask *ptr;
|
|
||||||
size_t size;
|
|
||||||
} mMaskList;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
const float *ptPtr;
|
|
||||||
size_t ptCount;
|
|
||||||
const char *elmPtr;
|
|
||||||
size_t elmCount;
|
|
||||||
} mClipPath;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct LOTLayerNode **ptr;
|
|
||||||
size_t size;
|
|
||||||
} mLayerList;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
LOTNode **ptr;
|
|
||||||
size_t size;
|
|
||||||
} mNodeList;
|
|
||||||
|
|
||||||
LOTMatteType mMatte;
|
|
||||||
int mVisible;
|
|
||||||
unsigned char mAlpha;
|
|
||||||
const char *keypath;
|
|
||||||
|
|
||||||
} LOTLayerNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif // _RLOTTIE_COMMON_H_
|
|
461
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_math.cpp
generated
vendored
461
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_math.cpp
generated
vendored
@ -1,461 +0,0 @@
|
|||||||
/***************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* fttrigon.c */
|
|
||||||
/* */
|
|
||||||
/* FreeType trigonometric functions (body). */
|
|
||||||
/* */
|
|
||||||
/* Copyright 2001-2005, 2012-2013 by */
|
|
||||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
||||||
/* */
|
|
||||||
/* This file is part of the FreeType project, and may only be used, */
|
|
||||||
/* modified, and distributed under the terms of the FreeType project */
|
|
||||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
||||||
/* this file you indicate that you have read the license and */
|
|
||||||
/* understand and accept it fully. */
|
|
||||||
/* */
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#include "vector_freetype_v_ft_math.h"
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
//form https://github.com/chromium/chromium/blob/59afd8336009c9d97c22854c52e0382b62b3aa5e/third_party/abseil-cpp/absl/base/internal/bits.h
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include <intrin.h>
|
|
||||||
static unsigned int __inline clz(unsigned int x) {
|
|
||||||
unsigned long r = 0;
|
|
||||||
if (x != 0)
|
|
||||||
{
|
|
||||||
_BitScanReverse(&r, x);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#define SW_FT_MSB(x) (clz(x))
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#define SW_FT_MSB(x) (31 - __builtin_clz(x))
|
|
||||||
#else
|
|
||||||
static unsigned int __inline clz(unsigned int x) {
|
|
||||||
int c = 31;
|
|
||||||
x &= ~x + 1;
|
|
||||||
if (n & 0x0000FFFF) c -= 16;
|
|
||||||
if (n & 0x00FF00FF) c -= 8;
|
|
||||||
if (n & 0x0F0F0F0F) c -= 4;
|
|
||||||
if (n & 0x33333333) c -= 2;
|
|
||||||
if (n & 0x55555555) c -= 1;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
#define SW_FT_MSB(x) (clz(x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SW_FT_PAD_FLOOR(x, n) ((x) & ~((n)-1))
|
|
||||||
#define SW_FT_PAD_ROUND(x, n) SW_FT_PAD_FLOOR((x) + ((n) / 2), n)
|
|
||||||
#define SW_FT_PAD_CEIL(x, n) SW_FT_PAD_FLOOR((x) + ((n)-1), n)
|
|
||||||
|
|
||||||
#define SW_FT_BEGIN_STMNT do {
|
|
||||||
#define SW_FT_END_STMNT \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
/* transfer sign leaving a positive number */
|
|
||||||
#define SW_FT_MOVE_SIGN(x, s) \
|
|
||||||
SW_FT_BEGIN_STMNT \
|
|
||||||
if (x < 0) { \
|
|
||||||
x = -x; \
|
|
||||||
s = -s; \
|
|
||||||
} \
|
|
||||||
SW_FT_END_STMNT
|
|
||||||
|
|
||||||
SW_FT_Long SW_FT_MulFix(SW_FT_Long a, SW_FT_Long b)
|
|
||||||
{
|
|
||||||
SW_FT_Int s = 1;
|
|
||||||
SW_FT_Long c;
|
|
||||||
|
|
||||||
SW_FT_MOVE_SIGN(a, s);
|
|
||||||
SW_FT_MOVE_SIGN(b, s);
|
|
||||||
|
|
||||||
c = (SW_FT_Long)(((SW_FT_Int64)a * b + 0x8000L) >> 16);
|
|
||||||
|
|
||||||
return (s > 0) ? c : -c;
|
|
||||||
}
|
|
||||||
|
|
||||||
SW_FT_Long SW_FT_MulDiv(SW_FT_Long a, SW_FT_Long b, SW_FT_Long c)
|
|
||||||
{
|
|
||||||
SW_FT_Int s = 1;
|
|
||||||
SW_FT_Long d;
|
|
||||||
|
|
||||||
SW_FT_MOVE_SIGN(a, s);
|
|
||||||
SW_FT_MOVE_SIGN(b, s);
|
|
||||||
SW_FT_MOVE_SIGN(c, s);
|
|
||||||
|
|
||||||
d = (SW_FT_Long)(c > 0 ? ((SW_FT_Int64)a * b + (c >> 1)) / c : 0x7FFFFFFFL);
|
|
||||||
|
|
||||||
return (s > 0) ? d : -d;
|
|
||||||
}
|
|
||||||
|
|
||||||
SW_FT_Long SW_FT_DivFix(SW_FT_Long a, SW_FT_Long b)
|
|
||||||
{
|
|
||||||
SW_FT_Int s = 1;
|
|
||||||
SW_FT_Long q;
|
|
||||||
|
|
||||||
SW_FT_MOVE_SIGN(a, s);
|
|
||||||
SW_FT_MOVE_SIGN(b, s);
|
|
||||||
|
|
||||||
q = (SW_FT_Long)(b > 0 ? (((SW_FT_UInt64)a << 16) + (b >> 1)) / b
|
|
||||||
: 0x7FFFFFFFL);
|
|
||||||
|
|
||||||
return (s < 0 ? -q : q);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* This is a fixed-point CORDIC implementation of trigonometric */
|
|
||||||
/* functions as well as transformations between Cartesian and polar */
|
|
||||||
/* coordinates. The angles are represented as 16.16 fixed-point values */
|
|
||||||
/* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */
|
|
||||||
/* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */
|
|
||||||
/* discrete Cartesian grid can have the same or better angular */
|
|
||||||
/* resolution. Therefore, to maintain this precision, some functions */
|
|
||||||
/* require an interim upscaling of the vectors, whereas others operate */
|
|
||||||
/* with 24-bit long vectors directly. */
|
|
||||||
/* */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
/* the Cordic shrink factor 0.858785336480436 * 2^32 */
|
|
||||||
#define SW_FT_TRIG_SCALE 0xDBD95B16UL
|
|
||||||
|
|
||||||
/* the highest bit in overflow-safe vector components, */
|
|
||||||
/* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */
|
|
||||||
#define SW_FT_TRIG_SAFE_MSB 29
|
|
||||||
|
|
||||||
/* this table was generated for SW_FT_PI = 180L << 16, i.e. degrees */
|
|
||||||
#define SW_FT_TRIG_MAX_ITERS 23
|
|
||||||
|
|
||||||
static const SW_FT_Fixed ft_trig_arctan_table[] = {
|
|
||||||
1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, 14668L,
|
|
||||||
7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, 57L,
|
|
||||||
29L, 14L, 7L, 4L, 2L, 1L};
|
|
||||||
|
|
||||||
/* multiply a given value by the CORDIC shrink factor */
|
|
||||||
static SW_FT_Fixed ft_trig_downscale(SW_FT_Fixed val)
|
|
||||||
{
|
|
||||||
SW_FT_Fixed s;
|
|
||||||
SW_FT_Int64 v;
|
|
||||||
|
|
||||||
s = val;
|
|
||||||
val = SW_FT_ABS(val);
|
|
||||||
|
|
||||||
v = (val * (SW_FT_Int64)SW_FT_TRIG_SCALE) + 0x100000000UL;
|
|
||||||
val = (SW_FT_Fixed)(v >> 32);
|
|
||||||
|
|
||||||
return (s >= 0) ? val : -val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* undefined and never called for zero vector */
|
|
||||||
static SW_FT_Int ft_trig_prenorm(SW_FT_Vector* vec)
|
|
||||||
{
|
|
||||||
SW_FT_Pos x, y;
|
|
||||||
SW_FT_Int shift;
|
|
||||||
|
|
||||||
x = vec->x;
|
|
||||||
y = vec->y;
|
|
||||||
|
|
||||||
shift = SW_FT_MSB(SW_FT_ABS(x) | SW_FT_ABS(y));
|
|
||||||
|
|
||||||
if (shift <= SW_FT_TRIG_SAFE_MSB) {
|
|
||||||
shift = SW_FT_TRIG_SAFE_MSB - shift;
|
|
||||||
vec->x = (SW_FT_Pos)((SW_FT_ULong)x << shift);
|
|
||||||
vec->y = (SW_FT_Pos)((SW_FT_ULong)y << shift);
|
|
||||||
} else {
|
|
||||||
shift -= SW_FT_TRIG_SAFE_MSB;
|
|
||||||
vec->x = x >> shift;
|
|
||||||
vec->y = y >> shift;
|
|
||||||
shift = -shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
return shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ft_trig_pseudo_rotate(SW_FT_Vector* vec, SW_FT_Angle theta)
|
|
||||||
{
|
|
||||||
SW_FT_Int i;
|
|
||||||
SW_FT_Fixed x, y, xtemp, b;
|
|
||||||
const SW_FT_Fixed* arctanptr;
|
|
||||||
|
|
||||||
x = vec->x;
|
|
||||||
y = vec->y;
|
|
||||||
|
|
||||||
/* Rotate inside [-PI/4,PI/4] sector */
|
|
||||||
while (theta < -SW_FT_ANGLE_PI4) {
|
|
||||||
xtemp = y;
|
|
||||||
y = -x;
|
|
||||||
x = xtemp;
|
|
||||||
theta += SW_FT_ANGLE_PI2;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (theta > SW_FT_ANGLE_PI4) {
|
|
||||||
xtemp = -y;
|
|
||||||
y = x;
|
|
||||||
x = xtemp;
|
|
||||||
theta -= SW_FT_ANGLE_PI2;
|
|
||||||
}
|
|
||||||
|
|
||||||
arctanptr = ft_trig_arctan_table;
|
|
||||||
|
|
||||||
/* Pseudorotations, with right shifts */
|
|
||||||
for (i = 1, b = 1; i < SW_FT_TRIG_MAX_ITERS; b <<= 1, i++) {
|
|
||||||
SW_FT_Fixed v1 = ((y + b) >> i);
|
|
||||||
SW_FT_Fixed v2 = ((x + b) >> i);
|
|
||||||
if (theta < 0) {
|
|
||||||
xtemp = x + v1;
|
|
||||||
y = y - v2;
|
|
||||||
x = xtemp;
|
|
||||||
theta += *arctanptr++;
|
|
||||||
} else {
|
|
||||||
xtemp = x - v1;
|
|
||||||
y = y + v2;
|
|
||||||
x = xtemp;
|
|
||||||
theta -= *arctanptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->x = x;
|
|
||||||
vec->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ft_trig_pseudo_polarize(SW_FT_Vector* vec)
|
|
||||||
{
|
|
||||||
SW_FT_Angle theta;
|
|
||||||
SW_FT_Int i;
|
|
||||||
SW_FT_Fixed x, y, xtemp, b;
|
|
||||||
const SW_FT_Fixed* arctanptr;
|
|
||||||
|
|
||||||
x = vec->x;
|
|
||||||
y = vec->y;
|
|
||||||
|
|
||||||
/* Get the vector into [-PI/4,PI/4] sector */
|
|
||||||
if (y > x) {
|
|
||||||
if (y > -x) {
|
|
||||||
theta = SW_FT_ANGLE_PI2;
|
|
||||||
xtemp = y;
|
|
||||||
y = -x;
|
|
||||||
x = xtemp;
|
|
||||||
} else {
|
|
||||||
theta = y > 0 ? SW_FT_ANGLE_PI : -SW_FT_ANGLE_PI;
|
|
||||||
x = -x;
|
|
||||||
y = -y;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (y < -x) {
|
|
||||||
theta = -SW_FT_ANGLE_PI2;
|
|
||||||
xtemp = -y;
|
|
||||||
y = x;
|
|
||||||
x = xtemp;
|
|
||||||
} else {
|
|
||||||
theta = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
arctanptr = ft_trig_arctan_table;
|
|
||||||
|
|
||||||
/* Pseudorotations, with right shifts */
|
|
||||||
for (i = 1, b = 1; i < SW_FT_TRIG_MAX_ITERS; b <<= 1, i++) {
|
|
||||||
SW_FT_Fixed v1 = ((y + b) >> i);
|
|
||||||
SW_FT_Fixed v2 = ((x + b) >> i);
|
|
||||||
if (y > 0) {
|
|
||||||
xtemp = x + v1;
|
|
||||||
y = y - v2;
|
|
||||||
x = xtemp;
|
|
||||||
theta += *arctanptr++;
|
|
||||||
} else {
|
|
||||||
xtemp = x - v1;
|
|
||||||
y = y + v2;
|
|
||||||
x = xtemp;
|
|
||||||
theta -= *arctanptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* round theta */
|
|
||||||
if (theta >= 0)
|
|
||||||
theta = SW_FT_PAD_ROUND(theta, 32);
|
|
||||||
else
|
|
||||||
theta = -SW_FT_PAD_ROUND(-theta, 32);
|
|
||||||
|
|
||||||
vec->x = x;
|
|
||||||
vec->y = theta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
SW_FT_Fixed SW_FT_Cos(SW_FT_Angle angle)
|
|
||||||
{
|
|
||||||
SW_FT_Vector v;
|
|
||||||
|
|
||||||
v.x = SW_FT_TRIG_SCALE >> 8;
|
|
||||||
v.y = 0;
|
|
||||||
ft_trig_pseudo_rotate(&v, angle);
|
|
||||||
|
|
||||||
return (v.x + 0x80L) >> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
SW_FT_Fixed SW_FT_Sin(SW_FT_Angle angle)
|
|
||||||
{
|
|
||||||
return SW_FT_Cos(SW_FT_ANGLE_PI2 - angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
SW_FT_Fixed SW_FT_Tan(SW_FT_Angle angle)
|
|
||||||
{
|
|
||||||
SW_FT_Vector v;
|
|
||||||
|
|
||||||
v.x = SW_FT_TRIG_SCALE >> 8;
|
|
||||||
v.y = 0;
|
|
||||||
ft_trig_pseudo_rotate(&v, angle);
|
|
||||||
|
|
||||||
return SW_FT_DivFix(v.y, v.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
SW_FT_Angle SW_FT_Atan2(SW_FT_Fixed dx, SW_FT_Fixed dy)
|
|
||||||
{
|
|
||||||
SW_FT_Vector v;
|
|
||||||
|
|
||||||
if (dx == 0 && dy == 0) return 0;
|
|
||||||
|
|
||||||
v.x = dx;
|
|
||||||
v.y = dy;
|
|
||||||
ft_trig_prenorm(&v);
|
|
||||||
ft_trig_pseudo_polarize(&v);
|
|
||||||
|
|
||||||
return v.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
void SW_FT_Vector_Unit(SW_FT_Vector* vec, SW_FT_Angle angle)
|
|
||||||
{
|
|
||||||
vec->x = SW_FT_TRIG_SCALE >> 8;
|
|
||||||
vec->y = 0;
|
|
||||||
ft_trig_pseudo_rotate(vec, angle);
|
|
||||||
vec->x = (vec->x + 0x80L) >> 8;
|
|
||||||
vec->y = (vec->y + 0x80L) >> 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* these macros return 0 for positive numbers,
|
|
||||||
and -1 for negative ones */
|
|
||||||
#define SW_FT_SIGN_LONG(x) ((x) >> (SW_FT_SIZEOF_LONG * 8 - 1))
|
|
||||||
#define SW_FT_SIGN_INT(x) ((x) >> (SW_FT_SIZEOF_INT * 8 - 1))
|
|
||||||
#define SW_FT_SIGN_INT32(x) ((x) >> 31)
|
|
||||||
#define SW_FT_SIGN_INT16(x) ((x) >> 15)
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
void SW_FT_Vector_Rotate(SW_FT_Vector* vec, SW_FT_Angle angle)
|
|
||||||
{
|
|
||||||
SW_FT_Int shift;
|
|
||||||
SW_FT_Vector v;
|
|
||||||
|
|
||||||
v.x = vec->x;
|
|
||||||
v.y = vec->y;
|
|
||||||
|
|
||||||
if (angle && (v.x != 0 || v.y != 0)) {
|
|
||||||
shift = ft_trig_prenorm(&v);
|
|
||||||
ft_trig_pseudo_rotate(&v, angle);
|
|
||||||
v.x = ft_trig_downscale(v.x);
|
|
||||||
v.y = ft_trig_downscale(v.y);
|
|
||||||
|
|
||||||
if (shift > 0) {
|
|
||||||
SW_FT_Int32 half = (SW_FT_Int32)1L << (shift - 1);
|
|
||||||
|
|
||||||
vec->x = (v.x + half + SW_FT_SIGN_LONG(v.x)) >> shift;
|
|
||||||
vec->y = (v.y + half + SW_FT_SIGN_LONG(v.y)) >> shift;
|
|
||||||
} else {
|
|
||||||
shift = -shift;
|
|
||||||
vec->x = (SW_FT_Pos)((SW_FT_ULong)v.x << shift);
|
|
||||||
vec->y = (SW_FT_Pos)((SW_FT_ULong)v.y << shift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
SW_FT_Fixed SW_FT_Vector_Length(SW_FT_Vector* vec)
|
|
||||||
{
|
|
||||||
SW_FT_Int shift;
|
|
||||||
SW_FT_Vector v;
|
|
||||||
|
|
||||||
v = *vec;
|
|
||||||
|
|
||||||
/* handle trivial cases */
|
|
||||||
if (v.x == 0) {
|
|
||||||
return SW_FT_ABS(v.y);
|
|
||||||
} else if (v.y == 0) {
|
|
||||||
return SW_FT_ABS(v.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* general case */
|
|
||||||
shift = ft_trig_prenorm(&v);
|
|
||||||
ft_trig_pseudo_polarize(&v);
|
|
||||||
|
|
||||||
v.x = ft_trig_downscale(v.x);
|
|
||||||
|
|
||||||
if (shift > 0) return (v.x + (1 << (shift - 1))) >> shift;
|
|
||||||
|
|
||||||
return (SW_FT_Fixed)((SW_FT_UInt32)v.x << -shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
void SW_FT_Vector_Polarize(SW_FT_Vector* vec, SW_FT_Fixed* length,
|
|
||||||
SW_FT_Angle* angle)
|
|
||||||
{
|
|
||||||
SW_FT_Int shift;
|
|
||||||
SW_FT_Vector v;
|
|
||||||
|
|
||||||
v = *vec;
|
|
||||||
|
|
||||||
if (v.x == 0 && v.y == 0) return;
|
|
||||||
|
|
||||||
shift = ft_trig_prenorm(&v);
|
|
||||||
ft_trig_pseudo_polarize(&v);
|
|
||||||
|
|
||||||
v.x = ft_trig_downscale(v.x);
|
|
||||||
|
|
||||||
*length = (shift >= 0) ? (v.x >> shift)
|
|
||||||
: (SW_FT_Fixed)((SW_FT_UInt32)v.x << -shift);
|
|
||||||
*angle = v.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
void SW_FT_Vector_From_Polar(SW_FT_Vector* vec, SW_FT_Fixed length,
|
|
||||||
SW_FT_Angle angle)
|
|
||||||
{
|
|
||||||
vec->x = length;
|
|
||||||
vec->y = 0;
|
|
||||||
|
|
||||||
SW_FT_Vector_Rotate(vec, angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* documentation is in fttrigon.h */
|
|
||||||
|
|
||||||
SW_FT_Angle SW_FT_Angle_Diff( SW_FT_Angle angle1, SW_FT_Angle angle2 )
|
|
||||||
{
|
|
||||||
SW_FT_Angle delta = angle2 - angle1;
|
|
||||||
|
|
||||||
while ( delta <= -SW_FT_ANGLE_PI )
|
|
||||||
delta += SW_FT_ANGLE_2PI;
|
|
||||||
|
|
||||||
while ( delta > SW_FT_ANGLE_PI )
|
|
||||||
delta -= SW_FT_ANGLE_2PI;
|
|
||||||
|
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END */
|
|
438
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_math.h
generated
vendored
438
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_math.h
generated
vendored
@ -1,438 +0,0 @@
|
|||||||
#ifndef V_FT_MATH_H
|
|
||||||
#define V_FT_MATH_H
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* fttrigon.h */
|
|
||||||
/* */
|
|
||||||
/* FreeType trigonometric functions (specification). */
|
|
||||||
/* */
|
|
||||||
/* Copyright 2001, 2003, 2005, 2007, 2013 by */
|
|
||||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
||||||
/* */
|
|
||||||
/* This file is part of the FreeType project, and may only be used, */
|
|
||||||
/* modified, and distributed under the terms of the FreeType project */
|
|
||||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
||||||
/* this file you indicate that you have read the license and */
|
|
||||||
/* understand and accept it fully. */
|
|
||||||
/* */
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#include "vector_freetype_v_ft_types.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* The min and max functions missing in C. As usual, be careful not to */
|
|
||||||
/* write things like SW_FT_MIN( a++, b++ ) to avoid side effects. */
|
|
||||||
/* */
|
|
||||||
#define SW_FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) )
|
|
||||||
#define SW_FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) )
|
|
||||||
|
|
||||||
#define SW_FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
|
|
||||||
* algorithm. We use alpha = 1, beta = 3/8, giving us results with a
|
|
||||||
* largest error less than 7% compared to the exact value.
|
|
||||||
*/
|
|
||||||
#define SW_FT_HYPOT( x, y ) \
|
|
||||||
( x = SW_FT_ABS( x ), \
|
|
||||||
y = SW_FT_ABS( y ), \
|
|
||||||
x > y ? x + ( 3 * y >> 3 ) \
|
|
||||||
: y + ( 3 * x >> 3 ) )
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Function> */
|
|
||||||
/* SW_FT_MulFix */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A very simple function used to perform the computation */
|
|
||||||
/* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */
|
|
||||||
/* used to multiply a given value by a 16.16 fixed-point factor. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* a :: The first multiplier. */
|
|
||||||
/* b :: The second multiplier. Use a 16.16 factor here whenever */
|
|
||||||
/* possible (see note below). */
|
|
||||||
/* */
|
|
||||||
/* <Return> */
|
|
||||||
/* The result of `(a*b)/0x10000'. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* This function has been optimized for the case where the absolute */
|
|
||||||
/* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
|
|
||||||
/* As this happens mainly when scaling from notional units to */
|
|
||||||
/* fractional pixels in FreeType, it resulted in noticeable speed */
|
|
||||||
/* improvements between versions 2.x and 1.x. */
|
|
||||||
/* */
|
|
||||||
/* As a conclusion, always try to place a 16.16 factor as the */
|
|
||||||
/* _second_ argument of this function; this can make a great */
|
|
||||||
/* difference. */
|
|
||||||
/* */
|
|
||||||
SW_FT_Long
|
|
||||||
SW_FT_MulFix( SW_FT_Long a,
|
|
||||||
SW_FT_Long b );
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Function> */
|
|
||||||
/* SW_FT_MulDiv */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A very simple function used to perform the computation `(a*b)/c' */
|
|
||||||
/* with maximum accuracy (it uses a 64-bit intermediate integer */
|
|
||||||
/* whenever necessary). */
|
|
||||||
/* */
|
|
||||||
/* This function isn't necessarily as fast as some processor specific */
|
|
||||||
/* operations, but is at least completely portable. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* a :: The first multiplier. */
|
|
||||||
/* b :: The second multiplier. */
|
|
||||||
/* c :: The divisor. */
|
|
||||||
/* */
|
|
||||||
/* <Return> */
|
|
||||||
/* The result of `(a*b)/c'. This function never traps when trying to */
|
|
||||||
/* divide by zero; it simply returns `MaxInt' or `MinInt' depending */
|
|
||||||
/* on the signs of `a' and `b'. */
|
|
||||||
/* */
|
|
||||||
SW_FT_Long
|
|
||||||
SW_FT_MulDiv( SW_FT_Long a,
|
|
||||||
SW_FT_Long b,
|
|
||||||
SW_FT_Long c );
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Function> */
|
|
||||||
/* SW_FT_DivFix */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A very simple function used to perform the computation */
|
|
||||||
/* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */
|
|
||||||
/* used to divide a given value by a 16.16 fixed-point factor. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* a :: The numerator. */
|
|
||||||
/* b :: The denominator. Use a 16.16 factor here. */
|
|
||||||
/* */
|
|
||||||
/* <Return> */
|
|
||||||
/* The result of `(a*0x10000)/b'. */
|
|
||||||
/* */
|
|
||||||
SW_FT_Long
|
|
||||||
SW_FT_DivFix( SW_FT_Long a,
|
|
||||||
SW_FT_Long b );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Section> */
|
|
||||||
/* computations */
|
|
||||||
/* */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @type:
|
|
||||||
* SW_FT_Angle
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* This type is used to model angle values in FreeType. Note that the
|
|
||||||
* angle is a 16.16 fixed-point value expressed in degrees.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef SW_FT_Fixed SW_FT_Angle;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @macro:
|
|
||||||
* SW_FT_ANGLE_PI
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* The angle pi expressed in @SW_FT_Angle units.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define SW_FT_ANGLE_PI ( 180L << 16 )
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @macro:
|
|
||||||
* SW_FT_ANGLE_2PI
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* The angle 2*pi expressed in @SW_FT_Angle units.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define SW_FT_ANGLE_2PI ( SW_FT_ANGLE_PI * 2 )
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @macro:
|
|
||||||
* SW_FT_ANGLE_PI2
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* The angle pi/2 expressed in @SW_FT_Angle units.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define SW_FT_ANGLE_PI2 ( SW_FT_ANGLE_PI / 2 )
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @macro:
|
|
||||||
* SW_FT_ANGLE_PI4
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* The angle pi/4 expressed in @SW_FT_Angle units.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define SW_FT_ANGLE_PI4 ( SW_FT_ANGLE_PI / 4 )
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Sin
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the sinus of a given angle in fixed-point format.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* angle ::
|
|
||||||
* The input angle.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* The sinus value.
|
|
||||||
*
|
|
||||||
* @note:
|
|
||||||
* If you need both the sinus and cosinus for a given angle, use the
|
|
||||||
* function @SW_FT_Vector_Unit.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SW_FT_Fixed
|
|
||||||
SW_FT_Sin( SW_FT_Angle angle );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Cos
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the cosinus of a given angle in fixed-point format.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* angle ::
|
|
||||||
* The input angle.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* The cosinus value.
|
|
||||||
*
|
|
||||||
* @note:
|
|
||||||
* If you need both the sinus and cosinus for a given angle, use the
|
|
||||||
* function @SW_FT_Vector_Unit.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SW_FT_Fixed
|
|
||||||
SW_FT_Cos( SW_FT_Angle angle );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Tan
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the tangent of a given angle in fixed-point format.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* angle ::
|
|
||||||
* The input angle.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* The tangent value.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SW_FT_Fixed
|
|
||||||
SW_FT_Tan( SW_FT_Angle angle );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Atan2
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the arc-tangent corresponding to a given vector (x,y) in
|
|
||||||
* the 2d plane.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* x ::
|
|
||||||
* The horizontal vector coordinate.
|
|
||||||
*
|
|
||||||
* y ::
|
|
||||||
* The vertical vector coordinate.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* The arc-tangent value (i.e. angle).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SW_FT_Angle
|
|
||||||
SW_FT_Atan2( SW_FT_Fixed x,
|
|
||||||
SW_FT_Fixed y );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Angle_Diff
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the difference between two angles. The result is always
|
|
||||||
* constrained to the ]-PI..PI] interval.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* angle1 ::
|
|
||||||
* First angle.
|
|
||||||
*
|
|
||||||
* angle2 ::
|
|
||||||
* Second angle.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* Constrained value of `value2-value1'.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SW_FT_Angle
|
|
||||||
SW_FT_Angle_Diff( SW_FT_Angle angle1,
|
|
||||||
SW_FT_Angle angle2 );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Vector_Unit
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the unit vector corresponding to a given angle. After the
|
|
||||||
* call, the value of `vec.x' will be `sin(angle)', and the value of
|
|
||||||
* `vec.y' will be `cos(angle)'.
|
|
||||||
*
|
|
||||||
* This function is useful to retrieve both the sinus and cosinus of a
|
|
||||||
* given angle quickly.
|
|
||||||
*
|
|
||||||
* @output:
|
|
||||||
* vec ::
|
|
||||||
* The address of target vector.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* angle ::
|
|
||||||
* The input angle.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Vector_Unit( SW_FT_Vector* vec,
|
|
||||||
SW_FT_Angle angle );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Vector_Rotate
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Rotate a vector by a given angle.
|
|
||||||
*
|
|
||||||
* @inout:
|
|
||||||
* vec ::
|
|
||||||
* The address of target vector.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* angle ::
|
|
||||||
* The input angle.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Vector_Rotate( SW_FT_Vector* vec,
|
|
||||||
SW_FT_Angle angle );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Vector_Length
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Return the length of a given vector.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* vec ::
|
|
||||||
* The address of target vector.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* The vector length, expressed in the same units that the original
|
|
||||||
* vector coordinates.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SW_FT_Fixed
|
|
||||||
SW_FT_Vector_Length( SW_FT_Vector* vec );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Vector_Polarize
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Compute both the length and angle of a given vector.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* vec ::
|
|
||||||
* The address of source vector.
|
|
||||||
*
|
|
||||||
* @output:
|
|
||||||
* length ::
|
|
||||||
* The vector length.
|
|
||||||
*
|
|
||||||
* angle ::
|
|
||||||
* The vector angle.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Vector_Polarize( SW_FT_Vector* vec,
|
|
||||||
SW_FT_Fixed *length,
|
|
||||||
SW_FT_Angle *angle );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Vector_From_Polar
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Compute vector coordinates from a length and angle.
|
|
||||||
*
|
|
||||||
* @output:
|
|
||||||
* vec ::
|
|
||||||
* The address of source vector.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* length ::
|
|
||||||
* The vector length.
|
|
||||||
*
|
|
||||||
* angle ::
|
|
||||||
* The vector angle.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Vector_From_Polar( SW_FT_Vector* vec,
|
|
||||||
SW_FT_Fixed length,
|
|
||||||
SW_FT_Angle angle );
|
|
||||||
|
|
||||||
|
|
||||||
#endif // V_FT_MATH_H
|
|
1423
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_raster.cpp
generated
vendored
1423
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_raster.cpp
generated
vendored
File diff suppressed because it is too large
Load Diff
607
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_raster.h
generated
vendored
607
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_raster.h
generated
vendored
@ -1,607 +0,0 @@
|
|||||||
#ifndef V_FT_IMG_H
|
|
||||||
#define V_FT_IMG_H
|
|
||||||
/***************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* ftimage.h */
|
|
||||||
/* */
|
|
||||||
/* FreeType glyph image formats and default raster interface */
|
|
||||||
/* (specification). */
|
|
||||||
/* */
|
|
||||||
/* Copyright 1996-2010, 2013 by */
|
|
||||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
||||||
/* */
|
|
||||||
/* This file is part of the FreeType project, and may only be used, */
|
|
||||||
/* modified, and distributed under the terms of the FreeType project */
|
|
||||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
||||||
/* this file you indicate that you have read the license and */
|
|
||||||
/* understand and accept it fully. */
|
|
||||||
/* */
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* Note: A `raster' is simply a scan-line converter, used to render */
|
|
||||||
/* SW_FT_Outlines into SW_FT_Bitmaps. */
|
|
||||||
/* */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "vector_freetype_v_ft_types.h"
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Struct> */
|
|
||||||
/* FT_BBox */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A structure used to hold an outline's bounding box, i.e., the */
|
|
||||||
/* coordinates of its extrema in the horizontal and vertical */
|
|
||||||
/* directions. */
|
|
||||||
/* */
|
|
||||||
/* <Fields> */
|
|
||||||
/* xMin :: The horizontal minimum (left-most). */
|
|
||||||
/* */
|
|
||||||
/* yMin :: The vertical minimum (bottom-most). */
|
|
||||||
/* */
|
|
||||||
/* xMax :: The horizontal maximum (right-most). */
|
|
||||||
/* */
|
|
||||||
/* yMax :: The vertical maximum (top-most). */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* The bounding box is specified with the coordinates of the lower */
|
|
||||||
/* left and the upper right corner. In PostScript, those values are */
|
|
||||||
/* often called (llx,lly) and (urx,ury), respectively. */
|
|
||||||
/* */
|
|
||||||
/* If `yMin' is negative, this value gives the glyph's descender. */
|
|
||||||
/* Otherwise, the glyph doesn't descend below the baseline. */
|
|
||||||
/* Similarly, if `ymax' is positive, this value gives the glyph's */
|
|
||||||
/* ascender. */
|
|
||||||
/* */
|
|
||||||
/* `xMin' gives the horizontal distance from the glyph's origin to */
|
|
||||||
/* the left edge of the glyph's bounding box. If `xMin' is negative, */
|
|
||||||
/* the glyph extends to the left of the origin. */
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_BBox_
|
|
||||||
{
|
|
||||||
SW_FT_Pos xMin, yMin;
|
|
||||||
SW_FT_Pos xMax, yMax;
|
|
||||||
|
|
||||||
} SW_FT_BBox;
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Struct> */
|
|
||||||
/* SW_FT_Outline */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* This structure is used to describe an outline to the scan-line */
|
|
||||||
/* converter. */
|
|
||||||
/* */
|
|
||||||
/* <Fields> */
|
|
||||||
/* n_contours :: The number of contours in the outline. */
|
|
||||||
/* */
|
|
||||||
/* n_points :: The number of points in the outline. */
|
|
||||||
/* */
|
|
||||||
/* points :: A pointer to an array of `n_points' @SW_FT_Vector */
|
|
||||||
/* elements, giving the outline's point coordinates. */
|
|
||||||
/* */
|
|
||||||
/* tags :: A pointer to an array of `n_points' chars, giving */
|
|
||||||
/* each outline point's type. */
|
|
||||||
/* */
|
|
||||||
/* If bit~0 is unset, the point is `off' the curve, */
|
|
||||||
/* i.e., a Bézier control point, while it is `on' if */
|
|
||||||
/* set. */
|
|
||||||
/* */
|
|
||||||
/* Bit~1 is meaningful for `off' points only. If set, */
|
|
||||||
/* it indicates a third-order Bézier arc control point; */
|
|
||||||
/* and a second-order control point if unset. */
|
|
||||||
/* */
|
|
||||||
/* If bit~2 is set, bits 5-7 contain the drop-out mode */
|
|
||||||
/* (as defined in the OpenType specification; the value */
|
|
||||||
/* is the same as the argument to the SCANMODE */
|
|
||||||
/* instruction). */
|
|
||||||
/* */
|
|
||||||
/* Bits 3 and~4 are reserved for internal purposes. */
|
|
||||||
/* */
|
|
||||||
/* contours :: An array of `n_contours' shorts, giving the end */
|
|
||||||
/* point of each contour within the outline. For */
|
|
||||||
/* example, the first contour is defined by the points */
|
|
||||||
/* `0' to `contours[0]', the second one is defined by */
|
|
||||||
/* the points `contours[0]+1' to `contours[1]', etc. */
|
|
||||||
/* */
|
|
||||||
/* flags :: A set of bit flags used to characterize the outline */
|
|
||||||
/* and give hints to the scan-converter and hinter on */
|
|
||||||
/* how to convert/grid-fit it. See @SW_FT_OUTLINE_FLAGS.*/
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_Outline_
|
|
||||||
{
|
|
||||||
short n_contours; /* number of contours in glyph */
|
|
||||||
short n_points; /* number of points in the glyph */
|
|
||||||
|
|
||||||
SW_FT_Vector* points; /* the outline's points */
|
|
||||||
char* tags; /* the points flags */
|
|
||||||
short* contours; /* the contour end points */
|
|
||||||
char* contours_flag; /* the contour open flags */
|
|
||||||
|
|
||||||
int flags; /* outline masks */
|
|
||||||
|
|
||||||
} SW_FT_Outline;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Enum> */
|
|
||||||
/* SW_FT_OUTLINE_FLAGS */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A list of bit-field constants use for the flags in an outline's */
|
|
||||||
/* `flags' field. */
|
|
||||||
/* */
|
|
||||||
/* <Values> */
|
|
||||||
/* SW_FT_OUTLINE_NONE :: */
|
|
||||||
/* Value~0 is reserved. */
|
|
||||||
/* */
|
|
||||||
/* SW_FT_OUTLINE_OWNER :: */
|
|
||||||
/* If set, this flag indicates that the outline's field arrays */
|
|
||||||
/* (i.e., `points', `flags', and `contours') are `owned' by the */
|
|
||||||
/* outline object, and should thus be freed when it is destroyed. */
|
|
||||||
/* */
|
|
||||||
/* SW_FT_OUTLINE_EVEN_ODD_FILL :: */
|
|
||||||
/* By default, outlines are filled using the non-zero winding rule. */
|
|
||||||
/* If set to 1, the outline will be filled using the even-odd fill */
|
|
||||||
/* rule (only works with the smooth rasterizer). */
|
|
||||||
/* */
|
|
||||||
/* SW_FT_OUTLINE_REVERSE_FILL :: */
|
|
||||||
/* By default, outside contours of an outline are oriented in */
|
|
||||||
/* clock-wise direction, as defined in the TrueType specification. */
|
|
||||||
/* This flag is set if the outline uses the opposite direction */
|
|
||||||
/* (typically for Type~1 fonts). This flag is ignored by the scan */
|
|
||||||
/* converter. */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* */
|
|
||||||
/* There exists a second mechanism to pass the drop-out mode to the */
|
|
||||||
/* B/W rasterizer; see the `tags' field in @SW_FT_Outline. */
|
|
||||||
/* */
|
|
||||||
/* Please refer to the description of the `SCANTYPE' instruction in */
|
|
||||||
/* the OpenType specification (in file `ttinst1.doc') how simple */
|
|
||||||
/* drop-outs, smart drop-outs, and stubs are defined. */
|
|
||||||
/* */
|
|
||||||
#define SW_FT_OUTLINE_NONE 0x0
|
|
||||||
#define SW_FT_OUTLINE_OWNER 0x1
|
|
||||||
#define SW_FT_OUTLINE_EVEN_ODD_FILL 0x2
|
|
||||||
#define SW_FT_OUTLINE_REVERSE_FILL 0x4
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
#define SW_FT_CURVE_TAG( flag ) ( flag & 3 )
|
|
||||||
|
|
||||||
#define SW_FT_CURVE_TAG_ON 1
|
|
||||||
#define SW_FT_CURVE_TAG_CONIC 0
|
|
||||||
#define SW_FT_CURVE_TAG_CUBIC 2
|
|
||||||
|
|
||||||
|
|
||||||
#define SW_FT_Curve_Tag_On SW_FT_CURVE_TAG_ON
|
|
||||||
#define SW_FT_Curve_Tag_Conic SW_FT_CURVE_TAG_CONIC
|
|
||||||
#define SW_FT_Curve_Tag_Cubic SW_FT_CURVE_TAG_CUBIC
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* A raster is a scan converter, in charge of rendering an outline into */
|
|
||||||
/* a a bitmap. This section contains the public API for rasters. */
|
|
||||||
/* */
|
|
||||||
/* Note that in FreeType 2, all rasters are now encapsulated within */
|
|
||||||
/* specific modules called `renderers'. See `ftrender.h' for more */
|
|
||||||
/* details on renderers. */
|
|
||||||
/* */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Raster */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A handle (pointer) to a raster object. Each object can be used */
|
|
||||||
/* independently to convert an outline into a bitmap or pixmap. */
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_RasterRec_* SW_FT_Raster;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Struct> */
|
|
||||||
/* SW_FT_Span */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A structure used to model a single span of gray (or black) pixels */
|
|
||||||
/* when rendering a monochrome or anti-aliased bitmap. */
|
|
||||||
/* */
|
|
||||||
/* <Fields> */
|
|
||||||
/* x :: The span's horizontal start position. */
|
|
||||||
/* */
|
|
||||||
/* len :: The span's length in pixels. */
|
|
||||||
/* */
|
|
||||||
/* coverage :: The span color/coverage, ranging from 0 (background) */
|
|
||||||
/* to 255 (foreground). Only used for anti-aliased */
|
|
||||||
/* rendering. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* This structure is used by the span drawing callback type named */
|
|
||||||
/* @SW_FT_SpanFunc that takes the y~coordinate of the span as a */
|
|
||||||
/* parameter. */
|
|
||||||
/* */
|
|
||||||
/* The coverage value is always between 0 and 255. If you want less */
|
|
||||||
/* gray values, the callback function has to reduce them. */
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_Span_
|
|
||||||
{
|
|
||||||
short x;
|
|
||||||
short y;
|
|
||||||
unsigned short len;
|
|
||||||
unsigned char coverage;
|
|
||||||
|
|
||||||
} SW_FT_Span;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <FuncType> */
|
|
||||||
/* SW_FT_SpanFunc */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A function used as a call-back by the anti-aliased renderer in */
|
|
||||||
/* order to let client applications draw themselves the gray pixel */
|
|
||||||
/* spans on each scan line. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* y :: The scanline's y~coordinate. */
|
|
||||||
/* */
|
|
||||||
/* count :: The number of spans to draw on this scanline. */
|
|
||||||
/* */
|
|
||||||
/* spans :: A table of `count' spans to draw on the scanline. */
|
|
||||||
/* */
|
|
||||||
/* user :: User-supplied data that is passed to the callback. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* This callback allows client applications to directly render the */
|
|
||||||
/* gray spans of the anti-aliased bitmap to any kind of surfaces. */
|
|
||||||
/* */
|
|
||||||
/* This can be used to write anti-aliased outlines directly to a */
|
|
||||||
/* given background bitmap, and even perform translucency. */
|
|
||||||
/* */
|
|
||||||
/* Note that the `count' field cannot be greater than a fixed value */
|
|
||||||
/* defined by the `SW_FT_MAX_GRAY_SPANS' configuration macro in */
|
|
||||||
/* `ftoption.h'. By default, this value is set to~32, which means */
|
|
||||||
/* that if there are more than 32~spans on a given scanline, the */
|
|
||||||
/* callback is called several times with the same `y' parameter in */
|
|
||||||
/* order to draw all callbacks. */
|
|
||||||
/* */
|
|
||||||
/* Otherwise, the callback is only called once per scan-line, and */
|
|
||||||
/* only for those scanlines that do have `gray' pixels on them. */
|
|
||||||
/* */
|
|
||||||
typedef void
|
|
||||||
(*SW_FT_SpanFunc)( int count,
|
|
||||||
const SW_FT_Span* spans,
|
|
||||||
void* user );
|
|
||||||
|
|
||||||
typedef void
|
|
||||||
(*SW_FT_BboxFunc)( int x, int y, int w, int h,
|
|
||||||
void* user);
|
|
||||||
|
|
||||||
#define SW_FT_Raster_Span_Func SW_FT_SpanFunc
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Enum> */
|
|
||||||
/* SW_FT_RASTER_FLAG_XXX */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A list of bit flag constants as used in the `flags' field of a */
|
|
||||||
/* @SW_FT_Raster_Params structure. */
|
|
||||||
/* */
|
|
||||||
/* <Values> */
|
|
||||||
/* SW_FT_RASTER_FLAG_DEFAULT :: This value is 0. */
|
|
||||||
/* */
|
|
||||||
/* SW_FT_RASTER_FLAG_AA :: This flag is set to indicate that an */
|
|
||||||
/* anti-aliased glyph image should be */
|
|
||||||
/* generated. Otherwise, it will be */
|
|
||||||
/* monochrome (1-bit). */
|
|
||||||
/* */
|
|
||||||
/* SW_FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */
|
|
||||||
/* rendering. In this mode, client */
|
|
||||||
/* applications must provide their own span */
|
|
||||||
/* callback. This lets them directly */
|
|
||||||
/* draw or compose over an existing bitmap. */
|
|
||||||
/* If this bit is not set, the target */
|
|
||||||
/* pixmap's buffer _must_ be zeroed before */
|
|
||||||
/* rendering. */
|
|
||||||
/* */
|
|
||||||
/* Note that for now, direct rendering is */
|
|
||||||
/* only possible with anti-aliased glyphs. */
|
|
||||||
/* */
|
|
||||||
/* SW_FT_RASTER_FLAG_CLIP :: This flag is only used in direct */
|
|
||||||
/* rendering mode. If set, the output will */
|
|
||||||
/* be clipped to a box specified in the */
|
|
||||||
/* `clip_box' field of the */
|
|
||||||
/* @SW_FT_Raster_Params structure. */
|
|
||||||
/* */
|
|
||||||
/* Note that by default, the glyph bitmap */
|
|
||||||
/* is clipped to the target pixmap, except */
|
|
||||||
/* in direct rendering mode where all spans */
|
|
||||||
/* are generated if no clipping box is set. */
|
|
||||||
/* */
|
|
||||||
#define SW_FT_RASTER_FLAG_DEFAULT 0x0
|
|
||||||
#define SW_FT_RASTER_FLAG_AA 0x1
|
|
||||||
#define SW_FT_RASTER_FLAG_DIRECT 0x2
|
|
||||||
#define SW_FT_RASTER_FLAG_CLIP 0x4
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Struct> */
|
|
||||||
/* SW_FT_Raster_Params */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A structure to hold the arguments used by a raster's render */
|
|
||||||
/* function. */
|
|
||||||
/* */
|
|
||||||
/* <Fields> */
|
|
||||||
/* target :: The target bitmap. */
|
|
||||||
/* */
|
|
||||||
/* source :: A pointer to the source glyph image (e.g., an */
|
|
||||||
/* @SW_FT_Outline). */
|
|
||||||
/* */
|
|
||||||
/* flags :: The rendering flags. */
|
|
||||||
/* */
|
|
||||||
/* gray_spans :: The gray span drawing callback. */
|
|
||||||
/* */
|
|
||||||
/* black_spans :: The black span drawing callback. UNIMPLEMENTED! */
|
|
||||||
/* */
|
|
||||||
/* bit_test :: The bit test callback. UNIMPLEMENTED! */
|
|
||||||
/* */
|
|
||||||
/* bit_set :: The bit set callback. UNIMPLEMENTED! */
|
|
||||||
/* */
|
|
||||||
/* user :: User-supplied data that is passed to each drawing */
|
|
||||||
/* callback. */
|
|
||||||
/* */
|
|
||||||
/* clip_box :: An optional clipping box. It is only used in */
|
|
||||||
/* direct rendering mode. Note that coordinates here */
|
|
||||||
/* should be expressed in _integer_ pixels (and not in */
|
|
||||||
/* 26.6 fixed-point units). */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* An anti-aliased glyph bitmap is drawn if the @SW_FT_RASTER_FLAG_AA */
|
|
||||||
/* bit flag is set in the `flags' field, otherwise a monochrome */
|
|
||||||
/* bitmap is generated. */
|
|
||||||
/* */
|
|
||||||
/* If the @SW_FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */
|
|
||||||
/* raster will call the `gray_spans' callback to draw gray pixel */
|
|
||||||
/* spans, in the case of an aa glyph bitmap, it will call */
|
|
||||||
/* `black_spans', and `bit_test' and `bit_set' in the case of a */
|
|
||||||
/* monochrome bitmap. This allows direct composition over a */
|
|
||||||
/* pre-existing bitmap through user-provided callbacks to perform the */
|
|
||||||
/* span drawing/composition. */
|
|
||||||
/* */
|
|
||||||
/* Note that the `bit_test' and `bit_set' callbacks are required when */
|
|
||||||
/* rendering a monochrome bitmap, as they are crucial to implement */
|
|
||||||
/* correct drop-out control as defined in the TrueType specification. */
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_Raster_Params_
|
|
||||||
{
|
|
||||||
const void* source;
|
|
||||||
int flags;
|
|
||||||
SW_FT_SpanFunc gray_spans;
|
|
||||||
SW_FT_BboxFunc bbox_cb;
|
|
||||||
void* user;
|
|
||||||
SW_FT_BBox clip_box;
|
|
||||||
|
|
||||||
} SW_FT_Raster_Params;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Function> */
|
|
||||||
/* SW_FT_Outline_Check */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* Check the contents of an outline descriptor. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* outline :: A handle to a source outline. */
|
|
||||||
/* */
|
|
||||||
/* <Return> */
|
|
||||||
/* FreeType error code. 0~means success. */
|
|
||||||
/* */
|
|
||||||
SW_FT_Error
|
|
||||||
SW_FT_Outline_Check( SW_FT_Outline* outline );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Function> */
|
|
||||||
/* SW_FT_Outline_Get_CBox */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* Return an outline's `control box'. The control box encloses all */
|
|
||||||
/* the outline's points, including Bézier control points. Though it */
|
|
||||||
/* coincides with the exact bounding box for most glyphs, it can be */
|
|
||||||
/* slightly larger in some situations (like when rotating an outline */
|
|
||||||
/* that contains Bézier outside arcs). */
|
|
||||||
/* */
|
|
||||||
/* Computing the control box is very fast, while getting the bounding */
|
|
||||||
/* box can take much more time as it needs to walk over all segments */
|
|
||||||
/* and arcs in the outline. To get the latter, you can use the */
|
|
||||||
/* `ftbbox' component, which is dedicated to this single task. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* outline :: A pointer to the source outline descriptor. */
|
|
||||||
/* */
|
|
||||||
/* <Output> */
|
|
||||||
/* acbox :: The outline's control box. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* See @SW_FT_Glyph_Get_CBox for a discussion of tricky fonts. */
|
|
||||||
/* */
|
|
||||||
void
|
|
||||||
SW_FT_Outline_Get_CBox( const SW_FT_Outline* outline,
|
|
||||||
SW_FT_BBox *acbox );
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <FuncType> */
|
|
||||||
/* SW_FT_Raster_NewFunc */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A function used to create a new raster object. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* memory :: A handle to the memory allocator. */
|
|
||||||
/* */
|
|
||||||
/* <Output> */
|
|
||||||
/* raster :: A handle to the new raster object. */
|
|
||||||
/* */
|
|
||||||
/* <Return> */
|
|
||||||
/* Error code. 0~means success. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* The `memory' parameter is a typeless pointer in order to avoid */
|
|
||||||
/* un-wanted dependencies on the rest of the FreeType code. In */
|
|
||||||
/* practice, it is an @SW_FT_Memory object, i.e., a handle to the */
|
|
||||||
/* standard FreeType memory allocator. However, this field can be */
|
|
||||||
/* completely ignored by a given raster implementation. */
|
|
||||||
/* */
|
|
||||||
typedef int
|
|
||||||
(*SW_FT_Raster_NewFunc)( SW_FT_Raster* raster );
|
|
||||||
|
|
||||||
#define SW_FT_Raster_New_Func SW_FT_Raster_NewFunc
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <FuncType> */
|
|
||||||
/* SW_FT_Raster_DoneFunc */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A function used to destroy a given raster object. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* raster :: A handle to the raster object. */
|
|
||||||
/* */
|
|
||||||
typedef void
|
|
||||||
(*SW_FT_Raster_DoneFunc)( SW_FT_Raster raster );
|
|
||||||
|
|
||||||
#define SW_FT_Raster_Done_Func SW_FT_Raster_DoneFunc
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <FuncType> */
|
|
||||||
/* SW_FT_Raster_ResetFunc */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* FreeType provides an area of memory called the `render pool', */
|
|
||||||
/* available to all registered rasters. This pool can be freely used */
|
|
||||||
/* during a given scan-conversion but is shared by all rasters. Its */
|
|
||||||
/* content is thus transient. */
|
|
||||||
/* */
|
|
||||||
/* This function is called each time the render pool changes, or just */
|
|
||||||
/* after a new raster object is created. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* raster :: A handle to the new raster object. */
|
|
||||||
/* */
|
|
||||||
/* pool_base :: The address in memory of the render pool. */
|
|
||||||
/* */
|
|
||||||
/* pool_size :: The size in bytes of the render pool. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* Rasters can ignore the render pool and rely on dynamic memory */
|
|
||||||
/* allocation if they want to (a handle to the memory allocator is */
|
|
||||||
/* passed to the raster constructor). However, this is not */
|
|
||||||
/* recommended for efficiency purposes. */
|
|
||||||
/* */
|
|
||||||
typedef void
|
|
||||||
(*SW_FT_Raster_ResetFunc)( SW_FT_Raster raster,
|
|
||||||
unsigned char* pool_base,
|
|
||||||
unsigned long pool_size );
|
|
||||||
|
|
||||||
#define SW_FT_Raster_Reset_Func SW_FT_Raster_ResetFunc
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <FuncType> */
|
|
||||||
/* SW_FT_Raster_RenderFunc */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* Invoke a given raster to scan-convert a given glyph image into a */
|
|
||||||
/* target bitmap. */
|
|
||||||
/* */
|
|
||||||
/* <Input> */
|
|
||||||
/* raster :: A handle to the raster object. */
|
|
||||||
/* */
|
|
||||||
/* params :: A pointer to an @SW_FT_Raster_Params structure used to */
|
|
||||||
/* store the rendering parameters. */
|
|
||||||
/* */
|
|
||||||
/* <Return> */
|
|
||||||
/* Error code. 0~means success. */
|
|
||||||
/* */
|
|
||||||
/* <Note> */
|
|
||||||
/* The exact format of the source image depends on the raster's glyph */
|
|
||||||
/* format defined in its @SW_FT_Raster_Funcs structure. It can be an */
|
|
||||||
/* @SW_FT_Outline or anything else in order to support a large array of */
|
|
||||||
/* glyph formats. */
|
|
||||||
/* */
|
|
||||||
/* Note also that the render function can fail and return a */
|
|
||||||
/* `SW_FT_Err_Unimplemented_Feature' error code if the raster used does */
|
|
||||||
/* not support direct composition. */
|
|
||||||
/* */
|
|
||||||
/* XXX: For now, the standard raster doesn't support direct */
|
|
||||||
/* composition but this should change for the final release (see */
|
|
||||||
/* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */
|
|
||||||
/* for examples of distinct implementations that support direct */
|
|
||||||
/* composition). */
|
|
||||||
/* */
|
|
||||||
typedef int
|
|
||||||
(*SW_FT_Raster_RenderFunc)( SW_FT_Raster raster,
|
|
||||||
const SW_FT_Raster_Params* params );
|
|
||||||
|
|
||||||
#define SW_FT_Raster_Render_Func SW_FT_Raster_RenderFunc
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Struct> */
|
|
||||||
/* SW_FT_Raster_Funcs */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A structure used to describe a given raster class to the library. */
|
|
||||||
/* */
|
|
||||||
/* <Fields> */
|
|
||||||
/* glyph_format :: The supported glyph format for this raster. */
|
|
||||||
/* */
|
|
||||||
/* raster_new :: The raster constructor. */
|
|
||||||
/* */
|
|
||||||
/* raster_reset :: Used to reset the render pool within the raster. */
|
|
||||||
/* */
|
|
||||||
/* raster_render :: A function to render a glyph into a given bitmap. */
|
|
||||||
/* */
|
|
||||||
/* raster_done :: The raster destructor. */
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_Raster_Funcs_
|
|
||||||
{
|
|
||||||
SW_FT_Raster_NewFunc raster_new;
|
|
||||||
SW_FT_Raster_ResetFunc raster_reset;
|
|
||||||
SW_FT_Raster_RenderFunc raster_render;
|
|
||||||
SW_FT_Raster_DoneFunc raster_done;
|
|
||||||
|
|
||||||
} SW_FT_Raster_Funcs;
|
|
||||||
|
|
||||||
|
|
||||||
extern const SW_FT_Raster_Funcs sw_ft_grays_raster;
|
|
||||||
|
|
||||||
#endif // V_FT_IMG_H
|
|
1936
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_stroker.cpp
generated
vendored
1936
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_stroker.cpp
generated
vendored
File diff suppressed because it is too large
Load Diff
319
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_stroker.h
generated
vendored
319
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_stroker.h
generated
vendored
@ -1,319 +0,0 @@
|
|||||||
#ifndef V_FT_STROKER_H
|
|
||||||
#define V_FT_STROKER_H
|
|
||||||
/***************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* ftstroke.h */
|
|
||||||
/* */
|
|
||||||
/* FreeType path stroker (specification). */
|
|
||||||
/* */
|
|
||||||
/* Copyright 2002-2006, 2008, 2009, 2011-2012 by */
|
|
||||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
||||||
/* */
|
|
||||||
/* This file is part of the FreeType project, and may only be used, */
|
|
||||||
/* modified, and distributed under the terms of the FreeType project */
|
|
||||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
|
||||||
/* this file you indicate that you have read the license and */
|
|
||||||
/* understand and accept it fully. */
|
|
||||||
/* */
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#include "vector_freetype_v_ft_raster.h"
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @type:
|
|
||||||
* SW_FT_Stroker
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Opaque handler to a path stroker object.
|
|
||||||
*/
|
|
||||||
typedef struct SW_FT_StrokerRec_* SW_FT_Stroker;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @enum:
|
|
||||||
* SW_FT_Stroker_LineJoin
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* These values determine how two joining lines are rendered
|
|
||||||
* in a stroker.
|
|
||||||
*
|
|
||||||
* @values:
|
|
||||||
* SW_FT_STROKER_LINEJOIN_ROUND ::
|
|
||||||
* Used to render rounded line joins. Circular arcs are used
|
|
||||||
* to join two lines smoothly.
|
|
||||||
*
|
|
||||||
* SW_FT_STROKER_LINEJOIN_BEVEL ::
|
|
||||||
* Used to render beveled line joins. The outer corner of
|
|
||||||
* the joined lines is filled by enclosing the triangular
|
|
||||||
* region of the corner with a straight line between the
|
|
||||||
* outer corners of each stroke.
|
|
||||||
*
|
|
||||||
* SW_FT_STROKER_LINEJOIN_MITER_FIXED ::
|
|
||||||
* Used to render mitered line joins, with fixed bevels if the
|
|
||||||
* miter limit is exceeded. The outer edges of the strokes
|
|
||||||
* for the two segments are extended until they meet at an
|
|
||||||
* angle. If the segments meet at too sharp an angle (such
|
|
||||||
* that the miter would extend from the intersection of the
|
|
||||||
* segments a distance greater than the product of the miter
|
|
||||||
* limit value and the border radius), then a bevel join (see
|
|
||||||
* above) is used instead. This prevents long spikes being
|
|
||||||
* created. SW_FT_STROKER_LINEJOIN_MITER_FIXED generates a miter
|
|
||||||
* line join as used in PostScript and PDF.
|
|
||||||
*
|
|
||||||
* SW_FT_STROKER_LINEJOIN_MITER_VARIABLE ::
|
|
||||||
* SW_FT_STROKER_LINEJOIN_MITER ::
|
|
||||||
* Used to render mitered line joins, with variable bevels if
|
|
||||||
* the miter limit is exceeded. The intersection of the
|
|
||||||
* strokes is clipped at a line perpendicular to the bisector
|
|
||||||
* of the angle between the strokes, at the distance from the
|
|
||||||
* intersection of the segments equal to the product of the
|
|
||||||
* miter limit value and the border radius. This prevents
|
|
||||||
* long spikes being created.
|
|
||||||
* SW_FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line
|
|
||||||
* join as used in XPS. SW_FT_STROKER_LINEJOIN_MITER is an alias
|
|
||||||
* for SW_FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for
|
|
||||||
* backwards compatibility.
|
|
||||||
*/
|
|
||||||
typedef enum SW_FT_Stroker_LineJoin_
|
|
||||||
{
|
|
||||||
SW_FT_STROKER_LINEJOIN_ROUND = 0,
|
|
||||||
SW_FT_STROKER_LINEJOIN_BEVEL = 1,
|
|
||||||
SW_FT_STROKER_LINEJOIN_MITER_VARIABLE = 2,
|
|
||||||
SW_FT_STROKER_LINEJOIN_MITER = SW_FT_STROKER_LINEJOIN_MITER_VARIABLE,
|
|
||||||
SW_FT_STROKER_LINEJOIN_MITER_FIXED = 3
|
|
||||||
|
|
||||||
} SW_FT_Stroker_LineJoin;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @enum:
|
|
||||||
* SW_FT_Stroker_LineCap
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* These values determine how the end of opened sub-paths are
|
|
||||||
* rendered in a stroke.
|
|
||||||
*
|
|
||||||
* @values:
|
|
||||||
* SW_FT_STROKER_LINECAP_BUTT ::
|
|
||||||
* The end of lines is rendered as a full stop on the last
|
|
||||||
* point itself.
|
|
||||||
*
|
|
||||||
* SW_FT_STROKER_LINECAP_ROUND ::
|
|
||||||
* The end of lines is rendered as a half-circle around the
|
|
||||||
* last point.
|
|
||||||
*
|
|
||||||
* SW_FT_STROKER_LINECAP_SQUARE ::
|
|
||||||
* The end of lines is rendered as a square around the
|
|
||||||
* last point.
|
|
||||||
*/
|
|
||||||
typedef enum SW_FT_Stroker_LineCap_
|
|
||||||
{
|
|
||||||
SW_FT_STROKER_LINECAP_BUTT = 0,
|
|
||||||
SW_FT_STROKER_LINECAP_ROUND,
|
|
||||||
SW_FT_STROKER_LINECAP_SQUARE
|
|
||||||
|
|
||||||
} SW_FT_Stroker_LineCap;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @enum:
|
|
||||||
* SW_FT_StrokerBorder
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* These values are used to select a given stroke border
|
|
||||||
* in @SW_FT_Stroker_GetBorderCounts and @SW_FT_Stroker_ExportBorder.
|
|
||||||
*
|
|
||||||
* @values:
|
|
||||||
* SW_FT_STROKER_BORDER_LEFT ::
|
|
||||||
* Select the left border, relative to the drawing direction.
|
|
||||||
*
|
|
||||||
* SW_FT_STROKER_BORDER_RIGHT ::
|
|
||||||
* Select the right border, relative to the drawing direction.
|
|
||||||
*
|
|
||||||
* @note:
|
|
||||||
* Applications are generally interested in the `inside' and `outside'
|
|
||||||
* borders. However, there is no direct mapping between these and the
|
|
||||||
* `left' and `right' ones, since this really depends on the glyph's
|
|
||||||
* drawing orientation, which varies between font formats.
|
|
||||||
*
|
|
||||||
* You can however use @SW_FT_Outline_GetInsideBorder and
|
|
||||||
* @SW_FT_Outline_GetOutsideBorder to get these.
|
|
||||||
*/
|
|
||||||
typedef enum SW_FT_StrokerBorder_
|
|
||||||
{
|
|
||||||
SW_FT_STROKER_BORDER_LEFT = 0,
|
|
||||||
SW_FT_STROKER_BORDER_RIGHT
|
|
||||||
|
|
||||||
} SW_FT_StrokerBorder;
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Stroker_New
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Create a new stroker object.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* library ::
|
|
||||||
* FreeType library handle.
|
|
||||||
*
|
|
||||||
* @output:
|
|
||||||
* astroker ::
|
|
||||||
* A new stroker object handle. NULL in case of error.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* FreeType error code. 0~means success.
|
|
||||||
*/
|
|
||||||
SW_FT_Error
|
|
||||||
SW_FT_Stroker_New( SW_FT_Stroker *astroker );
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Stroker_Set
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Reset a stroker object's attributes.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* stroker ::
|
|
||||||
* The target stroker handle.
|
|
||||||
*
|
|
||||||
* radius ::
|
|
||||||
* The border radius.
|
|
||||||
*
|
|
||||||
* line_cap ::
|
|
||||||
* The line cap style.
|
|
||||||
*
|
|
||||||
* line_join ::
|
|
||||||
* The line join style.
|
|
||||||
*
|
|
||||||
* miter_limit ::
|
|
||||||
* The miter limit for the SW_FT_STROKER_LINEJOIN_MITER_FIXED and
|
|
||||||
* SW_FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles,
|
|
||||||
* expressed as 16.16 fixed-point value.
|
|
||||||
*
|
|
||||||
* @note:
|
|
||||||
* The radius is expressed in the same units as the outline
|
|
||||||
* coordinates.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Stroker_Set( SW_FT_Stroker stroker,
|
|
||||||
SW_FT_Fixed radius,
|
|
||||||
SW_FT_Stroker_LineCap line_cap,
|
|
||||||
SW_FT_Stroker_LineJoin line_join,
|
|
||||||
SW_FT_Fixed miter_limit );
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Stroker_ParseOutline
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* A convenience function used to parse a whole outline with
|
|
||||||
* the stroker. The resulting outline(s) can be retrieved
|
|
||||||
* later by functions like @SW_FT_Stroker_GetCounts and @SW_FT_Stroker_Export.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* stroker ::
|
|
||||||
* The target stroker handle.
|
|
||||||
*
|
|
||||||
* outline ::
|
|
||||||
* The source outline.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* FreeType error code. 0~means success.
|
|
||||||
*
|
|
||||||
* @note:
|
|
||||||
* If `opened' is~0 (the default), the outline is treated as a closed
|
|
||||||
* path, and the stroker generates two distinct `border' outlines.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This function calls @SW_FT_Stroker_Rewind automatically.
|
|
||||||
*/
|
|
||||||
SW_FT_Error
|
|
||||||
SW_FT_Stroker_ParseOutline( SW_FT_Stroker stroker,
|
|
||||||
const SW_FT_Outline* outline);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Stroker_GetCounts
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Call this function once you have finished parsing your paths
|
|
||||||
* with the stroker. It returns the number of points and
|
|
||||||
* contours necessary to export all points/borders from the stroked
|
|
||||||
* outline/path.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* stroker ::
|
|
||||||
* The target stroker handle.
|
|
||||||
*
|
|
||||||
* @output:
|
|
||||||
* anum_points ::
|
|
||||||
* The number of points.
|
|
||||||
*
|
|
||||||
* anum_contours ::
|
|
||||||
* The number of contours.
|
|
||||||
*
|
|
||||||
* @return:
|
|
||||||
* FreeType error code. 0~means success.
|
|
||||||
*/
|
|
||||||
SW_FT_Error
|
|
||||||
SW_FT_Stroker_GetCounts( SW_FT_Stroker stroker,
|
|
||||||
SW_FT_UInt *anum_points,
|
|
||||||
SW_FT_UInt *anum_contours );
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Stroker_Export
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Call this function after @SW_FT_Stroker_GetBorderCounts to
|
|
||||||
* export all borders to your own @SW_FT_Outline structure.
|
|
||||||
*
|
|
||||||
* Note that this function appends the border points and
|
|
||||||
* contours to your outline, but does not try to resize its
|
|
||||||
* arrays.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* stroker ::
|
|
||||||
* The target stroker handle.
|
|
||||||
*
|
|
||||||
* outline ::
|
|
||||||
* The target outline handle.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Stroker_Export( SW_FT_Stroker stroker,
|
|
||||||
SW_FT_Outline* outline );
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
*
|
|
||||||
* @function:
|
|
||||||
* SW_FT_Stroker_Done
|
|
||||||
*
|
|
||||||
* @description:
|
|
||||||
* Destroy a stroker object.
|
|
||||||
*
|
|
||||||
* @input:
|
|
||||||
* stroker ::
|
|
||||||
* A stroker handle. Can be NULL.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SW_FT_Stroker_Done( SW_FT_Stroker stroker );
|
|
||||||
|
|
||||||
|
|
||||||
#endif // V_FT_STROKER_H
|
|
160
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_types.h
generated
vendored
160
vendor/github.com/Benau/go_rlottie/vector_freetype_v_ft_types.h
generated
vendored
@ -1,160 +0,0 @@
|
|||||||
#ifndef V_FT_TYPES_H
|
|
||||||
#define V_FT_TYPES_H
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Fixed */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* This type is used to store 16.16 fixed-point values, like scaling */
|
|
||||||
/* values or matrix coefficients. */
|
|
||||||
/* */
|
|
||||||
typedef signed long SW_FT_Fixed;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Int */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A typedef for the int type. */
|
|
||||||
/* */
|
|
||||||
typedef signed int SW_FT_Int;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_UInt */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A typedef for the unsigned int type. */
|
|
||||||
/* */
|
|
||||||
typedef unsigned int SW_FT_UInt;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Long */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A typedef for signed long. */
|
|
||||||
/* */
|
|
||||||
typedef signed long SW_FT_Long;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_ULong */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A typedef for unsigned long. */
|
|
||||||
/* */
|
|
||||||
typedef unsigned long SW_FT_ULong;
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Short */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A typedef for signed short. */
|
|
||||||
/* */
|
|
||||||
typedef signed short SW_FT_Short;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Byte */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A simple typedef for the _unsigned_ char type. */
|
|
||||||
/* */
|
|
||||||
typedef unsigned char SW_FT_Byte;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Bool */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A typedef of unsigned char, used for simple booleans. As usual, */
|
|
||||||
/* values 1 and~0 represent true and false, respectively. */
|
|
||||||
/* */
|
|
||||||
typedef unsigned char SW_FT_Bool;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Error */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* The FreeType error code type. A value of~0 is always interpreted */
|
|
||||||
/* as a successful operation. */
|
|
||||||
/* */
|
|
||||||
typedef int SW_FT_Error;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Type> */
|
|
||||||
/* SW_FT_Pos */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* The type SW_FT_Pos is used to store vectorial coordinates. Depending */
|
|
||||||
/* on the context, these can represent distances in integer font */
|
|
||||||
/* units, or 16.16, or 26.6 fixed-point pixel coordinates. */
|
|
||||||
/* */
|
|
||||||
typedef signed long SW_FT_Pos;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* <Struct> */
|
|
||||||
/* SW_FT_Vector */
|
|
||||||
/* */
|
|
||||||
/* <Description> */
|
|
||||||
/* A simple structure used to store a 2D vector; coordinates are of */
|
|
||||||
/* the SW_FT_Pos type. */
|
|
||||||
/* */
|
|
||||||
/* <Fields> */
|
|
||||||
/* x :: The horizontal coordinate. */
|
|
||||||
/* y :: The vertical coordinate. */
|
|
||||||
/* */
|
|
||||||
typedef struct SW_FT_Vector_
|
|
||||||
{
|
|
||||||
SW_FT_Pos x;
|
|
||||||
SW_FT_Pos y;
|
|
||||||
|
|
||||||
} SW_FT_Vector;
|
|
||||||
|
|
||||||
|
|
||||||
typedef long long int SW_FT_Int64;
|
|
||||||
typedef unsigned long long int SW_FT_UInt64;
|
|
||||||
|
|
||||||
typedef signed int SW_FT_Int32;
|
|
||||||
typedef unsigned int SW_FT_UInt32;
|
|
||||||
|
|
||||||
|
|
||||||
#define SW_FT_BOOL( x ) ( (SW_FT_Bool)( x ) )
|
|
||||||
|
|
||||||
#define SW_FT_SIZEOF_LONG 4
|
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // V_FT_TYPES_H
|
|
500
vendor/github.com/Benau/go_rlottie/vector_pixman_pixman-arm-neon-asm.S
generated
vendored
500
vendor/github.com/Benau/go_rlottie/vector_pixman_pixman-arm-neon-asm.S
generated
vendored
@ -1,500 +0,0 @@
|
|||||||
#include "config.h"
|
|
||||||
#ifdef USE_ARM_NEON
|
|
||||||
/*
|
|
||||||
* Copyright © 2009 Nokia Corporation
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file contains implementations of NEON optimized pixel processing
|
|
||||||
* functions. There is no full and detailed tutorial, but some functions
|
|
||||||
* (those which are exposing some new or interesting features) are
|
|
||||||
* extensively commented and can be used as examples.
|
|
||||||
*
|
|
||||||
* You may want to have a look at the comments for following functions:
|
|
||||||
* - pixman_composite_over_8888_0565_asm_neon
|
|
||||||
* - pixman_composite_over_n_8_0565_asm_neon
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Prevent the stack from becoming executable for no reason... */
|
|
||||||
#if defined(__linux__) && defined(__ELF__)
|
|
||||||
.section .note.GNU-stack,"",%progbits
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.text
|
|
||||||
.fpu neon
|
|
||||||
.arch armv7a
|
|
||||||
.object_arch armv4
|
|
||||||
.eabi_attribute 10, 0 /* suppress Tag_FP_arch */
|
|
||||||
.eabi_attribute 12, 0 /* suppress Tag_Advanced_SIMD_arch */
|
|
||||||
.arm
|
|
||||||
.altmacro
|
|
||||||
.p2align 2
|
|
||||||
|
|
||||||
|
|
||||||
//#include "pixman-arm-asm.h"
|
|
||||||
/* Supplementary macro for setting function attributes */
|
|
||||||
.macro pixman_asm_function fname
|
|
||||||
.func fname
|
|
||||||
.global fname
|
|
||||||
#ifdef __ELF__
|
|
||||||
.hidden fname
|
|
||||||
.type fname, %function
|
|
||||||
#endif
|
|
||||||
fname:
|
|
||||||
.endm
|
|
||||||
|
|
||||||
//#include "pixman-private.h"
|
|
||||||
/*
|
|
||||||
* The defines which are shared between C and assembly code
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* bilinear interpolation precision (must be < 8) */
|
|
||||||
#define BILINEAR_INTERPOLATION_BITS 7
|
|
||||||
#define BILINEAR_INTERPOLATION_RANGE (1 << BILINEAR_INTERPOLATION_BITS)
|
|
||||||
|
|
||||||
#include "vector_pixman_pixman-arm-neon-asm.h"
|
|
||||||
|
|
||||||
/* Global configuration options and preferences */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The code can optionally make use of unaligned memory accesses to improve
|
|
||||||
* performance of handling leading/trailing pixels for each scanline.
|
|
||||||
* Configuration variable RESPECT_STRICT_ALIGNMENT can be set to 0 for
|
|
||||||
* example in linux if unaligned memory accesses are not configured to
|
|
||||||
* generate.exceptions.
|
|
||||||
*/
|
|
||||||
.set RESPECT_STRICT_ALIGNMENT, 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set default prefetch type. There is a choice between the following options:
|
|
||||||
*
|
|
||||||
* PREFETCH_TYPE_NONE (may be useful for the ARM cores where PLD is set to work
|
|
||||||
* as NOP to workaround some HW bugs or for whatever other reason)
|
|
||||||
*
|
|
||||||
* PREFETCH_TYPE_SIMPLE (may be useful for simple single-issue ARM cores where
|
|
||||||
* advanced prefetch intruduces heavy overhead)
|
|
||||||
*
|
|
||||||
* PREFETCH_TYPE_ADVANCED (useful for superscalar cores such as ARM Cortex-A8
|
|
||||||
* which can run ARM and NEON instructions simultaneously so that extra ARM
|
|
||||||
* instructions do not add (many) extra cycles, but improve prefetch efficiency)
|
|
||||||
*
|
|
||||||
* Note: some types of function can't support advanced prefetch and fallback
|
|
||||||
* to simple one (those which handle 24bpp pixels)
|
|
||||||
*/
|
|
||||||
.set PREFETCH_TYPE_DEFAULT, PREFETCH_TYPE_ADVANCED
|
|
||||||
|
|
||||||
/* Prefetch distance in pixels for simple prefetch */
|
|
||||||
.set PREFETCH_DISTANCE_SIMPLE, 64
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implementation of pixman_composite_over_8888_0565_asm_neon
|
|
||||||
*
|
|
||||||
* This function takes a8r8g8b8 source buffer, r5g6b5 destination buffer and
|
|
||||||
* performs OVER compositing operation. Function fast_composite_over_8888_0565
|
|
||||||
* from pixman-fast-path.c does the same in C and can be used as a reference.
|
|
||||||
*
|
|
||||||
* First we need to have some NEON assembly code which can do the actual
|
|
||||||
* operation on the pixels and provide it to the template macro.
|
|
||||||
*
|
|
||||||
* Template macro quite conveniently takes care of emitting all the necessary
|
|
||||||
* code for memory reading and writing (including quite tricky cases of
|
|
||||||
* handling unaligned leading/trailing pixels), so we only need to deal with
|
|
||||||
* the data in NEON registers.
|
|
||||||
*
|
|
||||||
* NEON registers allocation in general is recommented to be the following:
|
|
||||||
* d0, d1, d2, d3 - contain loaded source pixel data
|
|
||||||
* d4, d5, d6, d7 - contain loaded destination pixels (if they are needed)
|
|
||||||
* d24, d25, d26, d27 - contain loading mask pixel data (if mask is used)
|
|
||||||
* d28, d29, d30, d31 - place for storing the result (destination pixels)
|
|
||||||
*
|
|
||||||
* As can be seen above, four 64-bit NEON registers are used for keeping
|
|
||||||
* intermediate pixel data and up to 8 pixels can be processed in one step
|
|
||||||
* for 32bpp formats (16 pixels for 16bpp, 32 pixels for 8bpp).
|
|
||||||
*
|
|
||||||
* This particular function uses the following registers allocation:
|
|
||||||
* d0, d1, d2, d3 - contain loaded source pixel data
|
|
||||||
* d4, d5 - contain loaded destination pixels (they are needed)
|
|
||||||
* d28, d29 - place for storing the result (destination pixels)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Step one. We need to have some code to do some arithmetics on pixel data.
|
|
||||||
* This is implemented as a pair of macros: '*_head' and '*_tail'. When used
|
|
||||||
* back-to-back, they take pixel data from {d0, d1, d2, d3} and {d4, d5},
|
|
||||||
* perform all the needed calculations and write the result to {d28, d29}.
|
|
||||||
* The rationale for having two macros and not just one will be explained
|
|
||||||
* later. In practice, any single monolitic function which does the work can
|
|
||||||
* be split into two parts in any arbitrary way without affecting correctness.
|
|
||||||
*
|
|
||||||
* There is one special trick here too. Common template macro can optionally
|
|
||||||
* make our life a bit easier by doing R, G, B, A color components
|
|
||||||
* deinterleaving for 32bpp pixel formats (and this feature is used in
|
|
||||||
* 'pixman_composite_over_8888_0565_asm_neon' function). So it means that
|
|
||||||
* instead of having 8 packed pixels in {d0, d1, d2, d3} registers, we
|
|
||||||
* actually use d0 register for blue channel (a vector of eight 8-bit
|
|
||||||
* values), d1 register for green, d2 for red and d3 for alpha. This
|
|
||||||
* simple conversion can be also done with a few NEON instructions:
|
|
||||||
*
|
|
||||||
* Packed to planar conversion:
|
|
||||||
* vuzp.8 d0, d1
|
|
||||||
* vuzp.8 d2, d3
|
|
||||||
* vuzp.8 d1, d3
|
|
||||||
* vuzp.8 d0, d2
|
|
||||||
*
|
|
||||||
* Planar to packed conversion:
|
|
||||||
* vzip.8 d0, d2
|
|
||||||
* vzip.8 d1, d3
|
|
||||||
* vzip.8 d2, d3
|
|
||||||
* vzip.8 d0, d1
|
|
||||||
*
|
|
||||||
* But pixel can be loaded directly in planar format using VLD4.8 NEON
|
|
||||||
* instruction. It is 1 cycle slower than VLD1.32, so this is not always
|
|
||||||
* desirable, that's why deinterleaving is optional.
|
|
||||||
*
|
|
||||||
* But anyway, here is the code:
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OK, now we got almost everything that we need. Using the above two
|
|
||||||
* macros, the work can be done right. But now we want to optimize
|
|
||||||
* it a bit. ARM Cortex-A8 is an in-order core, and benefits really
|
|
||||||
* a lot from good code scheduling and software pipelining.
|
|
||||||
*
|
|
||||||
* Let's construct some code, which will run in the core main loop.
|
|
||||||
* Some pseudo-code of the main loop will look like this:
|
|
||||||
* head
|
|
||||||
* while (...) {
|
|
||||||
* tail
|
|
||||||
* head
|
|
||||||
* }
|
|
||||||
* tail
|
|
||||||
*
|
|
||||||
* It may look a bit weird, but this setup allows to hide instruction
|
|
||||||
* latencies better and also utilize dual-issue capability more
|
|
||||||
* efficiently (make pairs of load-store and ALU instructions).
|
|
||||||
*
|
|
||||||
* So what we need now is a '*_tail_head' macro, which will be used
|
|
||||||
* in the core main loop. A trivial straightforward implementation
|
|
||||||
* of this macro would look like this:
|
|
||||||
*
|
|
||||||
* pixman_composite_over_8888_0565_process_pixblock_tail
|
|
||||||
* vst1.16 {d28, d29}, [DST_W, :128]!
|
|
||||||
* vld1.16 {d4, d5}, [DST_R, :128]!
|
|
||||||
* vld4.32 {d0, d1, d2, d3}, [SRC]!
|
|
||||||
* pixman_composite_over_8888_0565_process_pixblock_head
|
|
||||||
* cache_preload 8, 8
|
|
||||||
*
|
|
||||||
* Now it also got some VLD/VST instructions. We simply can't move from
|
|
||||||
* processing one block of pixels to the other one with just arithmetics.
|
|
||||||
* The previously processed data needs to be written to memory and new
|
|
||||||
* data needs to be fetched. Fortunately, this main loop does not deal
|
|
||||||
* with partial leading/trailing pixels and can load/store a full block
|
|
||||||
* of pixels in a bulk. Additionally, destination buffer is already
|
|
||||||
* 16 bytes aligned here (which is good for performance).
|
|
||||||
*
|
|
||||||
* New things here are DST_R, DST_W, SRC and MASK identifiers. These
|
|
||||||
* are the aliases for ARM registers which are used as pointers for
|
|
||||||
* accessing data. We maintain separate pointers for reading and writing
|
|
||||||
* destination buffer (DST_R and DST_W).
|
|
||||||
*
|
|
||||||
* Another new thing is 'cache_preload' macro. It is used for prefetching
|
|
||||||
* data into CPU L2 cache and improve performance when dealing with large
|
|
||||||
* images which are far larger than cache size. It uses one argument
|
|
||||||
* (actually two, but they need to be the same here) - number of pixels
|
|
||||||
* in a block. Looking into 'pixman-arm-neon-asm.h' can provide some
|
|
||||||
* details about this macro. Moreover, if good performance is needed
|
|
||||||
* the code from this macro needs to be copied into '*_tail_head' macro
|
|
||||||
* and mixed with the rest of code for optimal instructions scheduling.
|
|
||||||
* We are actually doing it below.
|
|
||||||
*
|
|
||||||
* Now after all the explanations, here is the optimized code.
|
|
||||||
* Different instruction streams (originaling from '*_head', '*_tail'
|
|
||||||
* and 'cache_preload' macro) use different indentation levels for
|
|
||||||
* better readability. Actually taking the code from one of these
|
|
||||||
* indentation levels and ignoring a few VLD/VST instructions would
|
|
||||||
* result in exactly the code from '*_head', '*_tail' or 'cache_preload'
|
|
||||||
* macro!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* And now the final part. We are using 'generate_composite_function' macro
|
|
||||||
* to put all the stuff together. We are specifying the name of the function
|
|
||||||
* which we want to get, number of bits per pixel for the source, mask and
|
|
||||||
* destination (0 if unused, like mask in this case). Next come some bit
|
|
||||||
* flags:
|
|
||||||
* FLAG_DST_READWRITE - tells that the destination buffer is both read
|
|
||||||
* and written, for write-only buffer we would use
|
|
||||||
* FLAG_DST_WRITEONLY flag instead
|
|
||||||
* FLAG_DEINTERLEAVE_32BPP - tells that we prefer to work with planar data
|
|
||||||
* and separate color channels for 32bpp format.
|
|
||||||
* The next things are:
|
|
||||||
* - the number of pixels processed per iteration (8 in this case, because
|
|
||||||
* that's the maximum what can fit into four 64-bit NEON registers).
|
|
||||||
* - prefetch distance, measured in pixel blocks. In this case it is 5 times
|
|
||||||
* by 8 pixels. That would be 40 pixels, or up to 160 bytes. Optimal
|
|
||||||
* prefetch distance can be selected by running some benchmarks.
|
|
||||||
*
|
|
||||||
* After that we specify some macros, these are 'default_init',
|
|
||||||
* 'default_cleanup' here which are empty (but it is possible to have custom
|
|
||||||
* init/cleanup macros to be able to save/restore some extra NEON registers
|
|
||||||
* like d8-d15 or do anything else) followed by
|
|
||||||
* 'pixman_composite_over_8888_0565_process_pixblock_head',
|
|
||||||
* 'pixman_composite_over_8888_0565_process_pixblock_tail' and
|
|
||||||
* 'pixman_composite_over_8888_0565_process_pixblock_tail_head'
|
|
||||||
* which we got implemented above.
|
|
||||||
*
|
|
||||||
* The last part is the NEON registers allocation scheme.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
.macro pixman_composite_out_reverse_8888_8888_process_pixblock_head
|
|
||||||
vmvn.8 d24, d3 /* get inverted alpha */
|
|
||||||
/* do alpha blending */
|
|
||||||
vmull.u8 q8, d24, d4
|
|
||||||
vmull.u8 q9, d24, d5
|
|
||||||
vmull.u8 q10, d24, d6
|
|
||||||
vmull.u8 q11, d24, d7
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_out_reverse_8888_8888_process_pixblock_tail
|
|
||||||
vrshr.u16 q14, q8, #8
|
|
||||||
vrshr.u16 q15, q9, #8
|
|
||||||
vrshr.u16 q12, q10, #8
|
|
||||||
vrshr.u16 q13, q11, #8
|
|
||||||
vraddhn.u16 d28, q14, q8
|
|
||||||
vraddhn.u16 d29, q15, q9
|
|
||||||
vraddhn.u16 d30, q12, q10
|
|
||||||
vraddhn.u16 d31, q13, q11
|
|
||||||
.endm
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
.macro pixman_composite_over_8888_8888_process_pixblock_head
|
|
||||||
pixman_composite_out_reverse_8888_8888_process_pixblock_head
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_over_8888_8888_process_pixblock_tail
|
|
||||||
pixman_composite_out_reverse_8888_8888_process_pixblock_tail
|
|
||||||
vqadd.u8 q14, q0, q14
|
|
||||||
vqadd.u8 q15, q1, q15
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_over_8888_8888_process_pixblock_tail_head
|
|
||||||
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
|
|
||||||
vrshr.u16 q14, q8, #8
|
|
||||||
PF add PF_X, PF_X, #8
|
|
||||||
PF tst PF_CTL, #0xF
|
|
||||||
vrshr.u16 q15, q9, #8
|
|
||||||
vrshr.u16 q12, q10, #8
|
|
||||||
vrshr.u16 q13, q11, #8
|
|
||||||
PF addne PF_X, PF_X, #8
|
|
||||||
PF subne PF_CTL, PF_CTL, #1
|
|
||||||
vraddhn.u16 d28, q14, q8
|
|
||||||
vraddhn.u16 d29, q15, q9
|
|
||||||
PF cmp PF_X, ORIG_W
|
|
||||||
vraddhn.u16 d30, q12, q10
|
|
||||||
vraddhn.u16 d31, q13, q11
|
|
||||||
vqadd.u8 q14, q0, q14
|
|
||||||
vqadd.u8 q15, q1, q15
|
|
||||||
fetch_src_pixblock
|
|
||||||
PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
|
|
||||||
vmvn.8 d22, d3
|
|
||||||
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
|
|
||||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
|
||||||
PF subge PF_X, PF_X, ORIG_W
|
|
||||||
vmull.u8 q8, d22, d4
|
|
||||||
PF subges PF_CTL, PF_CTL, #0x10
|
|
||||||
vmull.u8 q9, d22, d5
|
|
||||||
PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]!
|
|
||||||
vmull.u8 q10, d22, d6
|
|
||||||
PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
|
|
||||||
vmull.u8 q11, d22, d7
|
|
||||||
.endm
|
|
||||||
|
|
||||||
generate_composite_function \
|
|
||||||
pixman_composite_over_8888_8888_asm_neon, 32, 0, 32, \
|
|
||||||
FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
|
|
||||||
8, /* number of pixels, processed in a single block */ \
|
|
||||||
5, /* prefetch distance */ \
|
|
||||||
default_init, \
|
|
||||||
default_cleanup, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_head, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_tail, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_tail_head
|
|
||||||
|
|
||||||
generate_composite_function_single_scanline \
|
|
||||||
pixman_composite_scanline_over_asm_neon, 32, 0, 32, \
|
|
||||||
FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
|
|
||||||
8, /* number of pixels, processed in a single block */ \
|
|
||||||
default_init, \
|
|
||||||
default_cleanup, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_head, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_tail, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_tail_head
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
.macro pixman_composite_over_n_8888_process_pixblock_head
|
|
||||||
/* deinterleaved source pixels in {d0, d1, d2, d3} */
|
|
||||||
/* inverted alpha in {d24} */
|
|
||||||
/* destination pixels in {d4, d5, d6, d7} */
|
|
||||||
vmull.u8 q8, d24, d4
|
|
||||||
vmull.u8 q9, d24, d5
|
|
||||||
vmull.u8 q10, d24, d6
|
|
||||||
vmull.u8 q11, d24, d7
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_over_n_8888_process_pixblock_tail
|
|
||||||
vrshr.u16 q14, q8, #8
|
|
||||||
vrshr.u16 q15, q9, #8
|
|
||||||
vrshr.u16 q2, q10, #8
|
|
||||||
vrshr.u16 q3, q11, #8
|
|
||||||
vraddhn.u16 d28, q14, q8
|
|
||||||
vraddhn.u16 d29, q15, q9
|
|
||||||
vraddhn.u16 d30, q2, q10
|
|
||||||
vraddhn.u16 d31, q3, q11
|
|
||||||
vqadd.u8 q14, q0, q14
|
|
||||||
vqadd.u8 q15, q1, q15
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_over_n_8888_process_pixblock_tail_head
|
|
||||||
vrshr.u16 q14, q8, #8
|
|
||||||
vrshr.u16 q15, q9, #8
|
|
||||||
vrshr.u16 q2, q10, #8
|
|
||||||
vrshr.u16 q3, q11, #8
|
|
||||||
vraddhn.u16 d28, q14, q8
|
|
||||||
vraddhn.u16 d29, q15, q9
|
|
||||||
vraddhn.u16 d30, q2, q10
|
|
||||||
vraddhn.u16 d31, q3, q11
|
|
||||||
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
|
|
||||||
vqadd.u8 q14, q0, q14
|
|
||||||
PF add PF_X, PF_X, #8
|
|
||||||
PF tst PF_CTL, #0x0F
|
|
||||||
PF addne PF_X, PF_X, #8
|
|
||||||
PF subne PF_CTL, PF_CTL, #1
|
|
||||||
vqadd.u8 q15, q1, q15
|
|
||||||
PF cmp PF_X, ORIG_W
|
|
||||||
vmull.u8 q8, d24, d4
|
|
||||||
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
|
|
||||||
vmull.u8 q9, d24, d5
|
|
||||||
PF subge PF_X, PF_X, ORIG_W
|
|
||||||
vmull.u8 q10, d24, d6
|
|
||||||
PF subges PF_CTL, PF_CTL, #0x10
|
|
||||||
vmull.u8 q11, d24, d7
|
|
||||||
PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
|
|
||||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_over_n_8888_init
|
|
||||||
add DUMMY, sp, #ARGS_STACK_OFFSET
|
|
||||||
vld1.32 {d3[0]}, [DUMMY]
|
|
||||||
vdup.8 d0, d3[0]
|
|
||||||
vdup.8 d1, d3[1]
|
|
||||||
vdup.8 d2, d3[2]
|
|
||||||
vdup.8 d3, d3[3]
|
|
||||||
vmvn.8 d24, d3 /* get inverted alpha */
|
|
||||||
.endm
|
|
||||||
|
|
||||||
generate_composite_function \
|
|
||||||
pixman_composite_over_n_8888_asm_neon, 0, 0, 32, \
|
|
||||||
FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
|
|
||||||
8, /* number of pixels, processed in a single block */ \
|
|
||||||
5, /* prefetch distance */ \
|
|
||||||
pixman_composite_over_n_8888_init, \
|
|
||||||
default_cleanup, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_head, \
|
|
||||||
pixman_composite_over_8888_8888_process_pixblock_tail, \
|
|
||||||
pixman_composite_over_n_8888_process_pixblock_tail_head
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
.macro pixman_composite_src_n_8888_process_pixblock_head
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_src_n_8888_process_pixblock_tail
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_src_n_8888_process_pixblock_tail_head
|
|
||||||
vst1.32 {d0, d1, d2, d3}, [DST_W, :128]!
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_src_n_8888_init
|
|
||||||
add DUMMY, sp, #ARGS_STACK_OFFSET
|
|
||||||
vld1.32 {d0[0]}, [DUMMY]
|
|
||||||
vsli.u64 d0, d0, #32
|
|
||||||
vorr d1, d0, d0
|
|
||||||
vorr q1, q0, q0
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_src_n_8888_cleanup
|
|
||||||
.endm
|
|
||||||
|
|
||||||
generate_composite_function \
|
|
||||||
pixman_composite_src_n_8888_asm_neon, 0, 0, 32, \
|
|
||||||
FLAG_DST_WRITEONLY, \
|
|
||||||
8, /* number of pixels, processed in a single block */ \
|
|
||||||
0, /* prefetch distance */ \
|
|
||||||
pixman_composite_src_n_8888_init, \
|
|
||||||
pixman_composite_src_n_8888_cleanup, \
|
|
||||||
pixman_composite_src_n_8888_process_pixblock_head, \
|
|
||||||
pixman_composite_src_n_8888_process_pixblock_tail, \
|
|
||||||
pixman_composite_src_n_8888_process_pixblock_tail_head, \
|
|
||||||
0, /* dst_w_basereg */ \
|
|
||||||
0, /* dst_r_basereg */ \
|
|
||||||
0, /* src_basereg */ \
|
|
||||||
0 /* mask_basereg */
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
.macro pixman_composite_src_8888_8888_process_pixblock_head
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_src_8888_8888_process_pixblock_tail
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro pixman_composite_src_8888_8888_process_pixblock_tail_head
|
|
||||||
vst1.32 {d0, d1, d2, d3}, [DST_W, :128]!
|
|
||||||
fetch_src_pixblock
|
|
||||||
cache_preload 8, 8
|
|
||||||
.endm
|
|
||||||
|
|
||||||
generate_composite_function \
|
|
||||||
pixman_composite_src_8888_8888_asm_neon, 32, 0, 32, \
|
|
||||||
FLAG_DST_WRITEONLY, \
|
|
||||||
8, /* number of pixels, processed in a single block */ \
|
|
||||||
10, /* prefetch distance */ \
|
|
||||||
default_init, \
|
|
||||||
default_cleanup, \
|
|
||||||
pixman_composite_src_8888_8888_process_pixblock_head, \
|
|
||||||
pixman_composite_src_8888_8888_process_pixblock_tail, \
|
|
||||||
pixman_composite_src_8888_8888_process_pixblock_tail_head, \
|
|
||||||
0, /* dst_w_basereg */ \
|
|
||||||
0, /* dst_r_basereg */ \
|
|
||||||
0, /* src_basereg */ \
|
|
||||||
0 /* mask_basereg */
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
#endif
|
|
1126
vendor/github.com/Benau/go_rlottie/vector_pixman_pixman-arm-neon-asm.h
generated
vendored
1126
vendor/github.com/Benau/go_rlottie/vector_pixman_pixman-arm-neon-asm.h
generated
vendored
File diff suppressed because it is too large
Load Diff
59
vendor/github.com/Benau/go_rlottie/vector_stb_stb_image.cpp
generated
vendored
59
vendor/github.com/Benau/go_rlottie/vector_stb_stb_image.cpp
generated
vendored
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* configure stb_image about
|
|
||||||
* the image we will support
|
|
||||||
*/
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
|
||||||
|
|
||||||
#define STBI_ONLY_JPEG
|
|
||||||
#define STBI_ONLY_PNG
|
|
||||||
#define STBI_NO_HDR
|
|
||||||
#define STBI_NO_LINEAR
|
|
||||||
#define STBI_NO_GIF
|
|
||||||
#define STBI_NO_PIC
|
|
||||||
|
|
||||||
#include "vector_stb_stb_image.h"
|
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
|
||||||
#ifdef RLOTTIE_BUILD
|
|
||||||
#define RLOTTIE_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define RLOTTIE_API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef RLOTTIE_BUILD
|
|
||||||
#define RLOTTIE_API __attribute__ ((visibility ("default")))
|
|
||||||
#else
|
|
||||||
#define RLOTTIE_API
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exported function wrapper from the library
|
|
||||||
*/
|
|
||||||
|
|
||||||
RLOTTIE_API unsigned char *lottie_image_load(char const *filename, int *x,
|
|
||||||
int *y, int *comp, int req_comp)
|
|
||||||
{
|
|
||||||
return stbi_load(filename, x, y, comp, req_comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API unsigned char *lottie_image_load_from_data(const char *imageData,
|
|
||||||
int len, int *x, int *y,
|
|
||||||
int *comp, int req_comp)
|
|
||||||
{
|
|
||||||
unsigned char *data = (unsigned char *)imageData;
|
|
||||||
return stbi_load_from_memory(data, len, x, y, comp, req_comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
RLOTTIE_API void lottie_image_free(unsigned char *data)
|
|
||||||
{
|
|
||||||
stbi_image_free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
7509
vendor/github.com/Benau/go_rlottie/vector_stb_stb_image.h
generated
vendored
7509
vendor/github.com/Benau/go_rlottie/vector_stb_stb_image.h
generated
vendored
File diff suppressed because it is too large
Load Diff
166
vendor/github.com/Benau/go_rlottie/vector_varenaalloc.cpp
generated
vendored
166
vendor/github.com/Benau/go_rlottie/vector_varenaalloc.cpp
generated
vendored
@ -1,166 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vector_varenaalloc.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
static char* end_chain(char*) { return nullptr; }
|
|
||||||
|
|
||||||
static uint32_t first_allocated_block(uint32_t blockSize, uint32_t firstHeapAllocation) {
|
|
||||||
return firstHeapAllocation > 0 ? firstHeapAllocation :
|
|
||||||
blockSize > 0 ? blockSize : 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
VArenaAlloc::VArenaAlloc(char* block, size_t size, size_t firstHeapAllocation)
|
|
||||||
: fDtorCursor {block}
|
|
||||||
, fCursor {block}
|
|
||||||
, fEnd {block + ToU32(size)}
|
|
||||||
, fFirstBlock {block}
|
|
||||||
, fFirstSize {ToU32(size)}
|
|
||||||
, fFirstHeapAllocationSize {first_allocated_block(ToU32(size), ToU32(firstHeapAllocation))}
|
|
||||||
{
|
|
||||||
if (size < sizeof(Footer)) {
|
|
||||||
fEnd = fCursor = fDtorCursor = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fCursor != nullptr) {
|
|
||||||
this->installFooter(end_chain, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VArenaAlloc::~VArenaAlloc() {
|
|
||||||
RunDtorsOnBlock(fDtorCursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VArenaAlloc::reset() {
|
|
||||||
this->~VArenaAlloc();
|
|
||||||
new (this) VArenaAlloc{fFirstBlock, fFirstSize, fFirstHeapAllocationSize};
|
|
||||||
}
|
|
||||||
|
|
||||||
void VArenaAlloc::installFooter(FooterAction* action, uint32_t padding) {
|
|
||||||
assert(padding < 64);
|
|
||||||
int64_t actionInt = (int64_t)(intptr_t)action;
|
|
||||||
|
|
||||||
// The top 14 bits should be either all 0s or all 1s. Check this.
|
|
||||||
assert((actionInt << 6) >> 6 == actionInt);
|
|
||||||
Footer encodedFooter = (actionInt << 6) | padding;
|
|
||||||
memmove(fCursor, &encodedFooter, sizeof(Footer));
|
|
||||||
fCursor += sizeof(Footer);
|
|
||||||
fDtorCursor = fCursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VArenaAlloc::installPtrFooter(FooterAction* action, char* ptr, uint32_t padding) {
|
|
||||||
memmove(fCursor, &ptr, sizeof(char*));
|
|
||||||
fCursor += sizeof(char*);
|
|
||||||
this->installFooter(action, padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* VArenaAlloc::SkipPod(char* footerEnd) {
|
|
||||||
char* objEnd = footerEnd - (sizeof(Footer) + sizeof(int32_t));
|
|
||||||
int32_t skip;
|
|
||||||
memmove(&skip, objEnd, sizeof(int32_t));
|
|
||||||
return objEnd - skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VArenaAlloc::RunDtorsOnBlock(char* footerEnd) {
|
|
||||||
while (footerEnd != nullptr) {
|
|
||||||
Footer footer;
|
|
||||||
memcpy(&footer, footerEnd - sizeof(Footer), sizeof(Footer));
|
|
||||||
|
|
||||||
FooterAction* action = (FooterAction*)(footer >> 6);
|
|
||||||
ptrdiff_t padding = footer & 63;
|
|
||||||
|
|
||||||
footerEnd = action(footerEnd) - padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* VArenaAlloc::NextBlock(char* footerEnd) {
|
|
||||||
char* objEnd = footerEnd - (sizeof(Footer) + sizeof(char*));
|
|
||||||
char* next;
|
|
||||||
memmove(&next, objEnd, sizeof(char*));
|
|
||||||
RunDtorsOnBlock(next);
|
|
||||||
delete [] objEnd;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VArenaAlloc::installUint32Footer(FooterAction* action, uint32_t value, uint32_t padding) {
|
|
||||||
memmove(fCursor, &value, sizeof(uint32_t));
|
|
||||||
fCursor += sizeof(uint32_t);
|
|
||||||
this->installFooter(action, padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) {
|
|
||||||
constexpr uint32_t headerSize = sizeof(Footer) + sizeof(ptrdiff_t);
|
|
||||||
// The chrome c++ library we use does not define std::max_align_t.
|
|
||||||
// This must be conservative to add the right amount of extra memory to handle the alignment
|
|
||||||
// padding.
|
|
||||||
constexpr uint32_t alignof_max_align_t = 8;
|
|
||||||
constexpr uint32_t maxSize = std::numeric_limits<uint32_t>::max();
|
|
||||||
constexpr uint32_t overhead = headerSize + sizeof(Footer);
|
|
||||||
AssertRelease(size <= maxSize - overhead);
|
|
||||||
uint32_t objSizeAndOverhead = size + overhead;
|
|
||||||
if (alignment > alignof_max_align_t) {
|
|
||||||
uint32_t alignmentOverhead = alignment - 1;
|
|
||||||
AssertRelease(objSizeAndOverhead <= maxSize - alignmentOverhead);
|
|
||||||
objSizeAndOverhead += alignmentOverhead;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t minAllocationSize;
|
|
||||||
if (fFirstHeapAllocationSize <= maxSize / fFib0) {
|
|
||||||
minAllocationSize = fFirstHeapAllocationSize * fFib0;
|
|
||||||
fFib0 += fFib1;
|
|
||||||
std::swap(fFib0, fFib1);
|
|
||||||
} else {
|
|
||||||
minAllocationSize = maxSize;
|
|
||||||
}
|
|
||||||
uint32_t allocationSize = std::max(objSizeAndOverhead, minAllocationSize);
|
|
||||||
|
|
||||||
// Round up to a nice size. If > 32K align to 4K boundary else up to max_align_t. The > 32K
|
|
||||||
// heuristic is from the JEMalloc behavior.
|
|
||||||
{
|
|
||||||
uint32_t mask = allocationSize > (1 << 15) ? (1 << 12) - 1 : 16 - 1;
|
|
||||||
AssertRelease(allocationSize <= maxSize - mask);
|
|
||||||
allocationSize = (allocationSize + mask) & ~mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* newBlock = new char[allocationSize];
|
|
||||||
|
|
||||||
auto previousDtor = fDtorCursor;
|
|
||||||
fCursor = newBlock;
|
|
||||||
fDtorCursor = newBlock;
|
|
||||||
fEnd = fCursor + allocationSize;
|
|
||||||
this->installPtrFooter(NextBlock, previousDtor, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* VArenaAlloc::allocObjectWithFooter(uint32_t sizeIncludingFooter, uint32_t alignment) {
|
|
||||||
uintptr_t mask = alignment - 1;
|
|
||||||
|
|
||||||
restart:
|
|
||||||
uint32_t skipOverhead = 0;
|
|
||||||
bool needsSkipFooter = fCursor != fDtorCursor;
|
|
||||||
if (needsSkipFooter) {
|
|
||||||
skipOverhead = sizeof(Footer) + sizeof(uint32_t);
|
|
||||||
}
|
|
||||||
char* objStart = (char*)((uintptr_t)(fCursor + skipOverhead + mask) & ~mask);
|
|
||||||
uint32_t totalSize = sizeIncludingFooter + skipOverhead;
|
|
||||||
//std::cout<<"non POD object size = "<<totalSize<<"\n";
|
|
||||||
if ((ptrdiff_t)totalSize > fEnd - objStart) {
|
|
||||||
this->ensureSpace(totalSize, alignment);
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssertRelease((ptrdiff_t)totalSize <= fEnd - objStart);
|
|
||||||
|
|
||||||
// Install a skip footer if needed, thus terminating a run of POD data. The calling code is
|
|
||||||
// responsible for installing the footer after the object.
|
|
||||||
if (needsSkipFooter) {
|
|
||||||
this->installUint32Footer(SkipPod, ToU32(fCursor - fDtorCursor), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objStart;
|
|
||||||
}
|
|
232
vendor/github.com/Benau/go_rlottie/vector_varenaalloc.h
generated
vendored
232
vendor/github.com/Benau/go_rlottie/vector_varenaalloc.h
generated
vendored
@ -1,232 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VARENAALLOC_H
|
|
||||||
#define VARENAALLOC_H
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <limits>
|
|
||||||
#include <new>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// SkArenaAlloc allocates object and destroys the allocated objects when destroyed. It's designed
|
|
||||||
// to minimize the number of underlying block allocations. SkArenaAlloc allocates first out of an
|
|
||||||
// (optional) user-provided block of memory, and when that's exhausted it allocates on the heap,
|
|
||||||
// starting with an allocation of firstHeapAllocation bytes. If your data (plus a small overhead)
|
|
||||||
// fits in the user-provided block, SkArenaAlloc never uses the heap, and if it fits in
|
|
||||||
// firstHeapAllocation bytes, it'll use the heap only once. If 0 is specified for
|
|
||||||
// firstHeapAllocation, then blockSize is used unless that too is 0, then 1024 is used.
|
|
||||||
//
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// char block[mostCasesSize];
|
|
||||||
// SkArenaAlloc arena(block, mostCasesSize);
|
|
||||||
//
|
|
||||||
// If mostCasesSize is too large for the stack, you can use the following pattern.
|
|
||||||
//
|
|
||||||
// std::unique_ptr<char[]> block{new char[mostCasesSize]};
|
|
||||||
// SkArenaAlloc arena(block.get(), mostCasesSize, almostAllCasesSize);
|
|
||||||
//
|
|
||||||
// If the program only sometimes allocates memory, use the following pattern.
|
|
||||||
//
|
|
||||||
// SkArenaAlloc arena(nullptr, 0, almostAllCasesSize);
|
|
||||||
//
|
|
||||||
// The storage does not necessarily need to be on the stack. Embedding the storage in a class also
|
|
||||||
// works.
|
|
||||||
//
|
|
||||||
// class Foo {
|
|
||||||
// char storage[mostCasesSize];
|
|
||||||
// SkArenaAlloc arena (storage, mostCasesSize);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// In addition, the system is optimized to handle POD data including arrays of PODs (where
|
|
||||||
// POD is really data with no destructors). For POD data it has zero overhead per item, and a
|
|
||||||
// typical per block overhead of 8 bytes. For non-POD objects there is a per item overhead of 4
|
|
||||||
// bytes. For arrays of non-POD objects there is a per array overhead of typically 8 bytes. There
|
|
||||||
// is an addition overhead when switching from POD data to non-POD data of typically 8 bytes.
|
|
||||||
//
|
|
||||||
// If additional blocks are needed they are increased exponentially. This strategy bounds the
|
|
||||||
// recursion of the RunDtorsOnBlock to be limited to O(log size-of-memory). Block size grow using
|
|
||||||
// the Fibonacci sequence which means that for 2^32 memory there are 48 allocations, and for 2^48
|
|
||||||
// there are 71 allocations.
|
|
||||||
class VArenaAlloc {
|
|
||||||
public:
|
|
||||||
VArenaAlloc(char* block, size_t blockSize, size_t firstHeapAllocation);
|
|
||||||
|
|
||||||
explicit VArenaAlloc(size_t firstHeapAllocation)
|
|
||||||
: VArenaAlloc(nullptr, 0, firstHeapAllocation)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~VArenaAlloc();
|
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
|
||||||
T* make(Args&&... args) {
|
|
||||||
uint32_t size = ToU32(sizeof(T));
|
|
||||||
uint32_t alignment = ToU32(alignof(T));
|
|
||||||
char* objStart;
|
|
||||||
if (std::is_trivially_destructible<T>::value) {
|
|
||||||
objStart = this->allocObject(size, alignment);
|
|
||||||
fCursor = objStart + size;
|
|
||||||
} else {
|
|
||||||
objStart = this->allocObjectWithFooter(size + sizeof(Footer), alignment);
|
|
||||||
// Can never be UB because max value is alignof(T).
|
|
||||||
uint32_t padding = ToU32(objStart - fCursor);
|
|
||||||
|
|
||||||
// Advance to end of object to install footer.
|
|
||||||
fCursor = objStart + size;
|
|
||||||
FooterAction* releaser = [](char* objEnd) {
|
|
||||||
char* objStart = objEnd - (sizeof(T) + sizeof(Footer));
|
|
||||||
((T*)objStart)->~T();
|
|
||||||
return objStart;
|
|
||||||
};
|
|
||||||
this->installFooter(releaser, padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This must be last to make objects with nested use of this allocator work.
|
|
||||||
return new(objStart) T(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T* makeArrayDefault(size_t count) {
|
|
||||||
uint32_t safeCount = ToU32(count);
|
|
||||||
T* array = (T*)this->commonArrayAlloc<T>(safeCount);
|
|
||||||
|
|
||||||
// If T is primitive then no initialization takes place.
|
|
||||||
for (size_t i = 0; i < safeCount; i++) {
|
|
||||||
new (&array[i]) T;
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T* makeArray(size_t count) {
|
|
||||||
uint32_t safeCount = ToU32(count);
|
|
||||||
T* array = (T*)this->commonArrayAlloc<T>(safeCount);
|
|
||||||
|
|
||||||
// If T is primitive then the memory is initialized. For example, an array of chars will
|
|
||||||
// be zeroed.
|
|
||||||
for (size_t i = 0; i < safeCount; i++) {
|
|
||||||
new (&array[i]) T();
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only use makeBytesAlignedTo if none of the typed variants are impractical to use.
|
|
||||||
void* makeBytesAlignedTo(size_t size, size_t align) {
|
|
||||||
auto objStart = this->allocObject(ToU32(size), ToU32(align));
|
|
||||||
fCursor = objStart + size;
|
|
||||||
return objStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy all allocated objects, free any heap allocations.
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void AssertRelease(bool cond) { if (!cond) { ::abort(); } }
|
|
||||||
static uint32_t ToU32(size_t v) {
|
|
||||||
return (uint32_t)v;
|
|
||||||
}
|
|
||||||
|
|
||||||
using Footer = int64_t;
|
|
||||||
using FooterAction = char* (char*);
|
|
||||||
|
|
||||||
static char* SkipPod(char* footerEnd);
|
|
||||||
static void RunDtorsOnBlock(char* footerEnd);
|
|
||||||
static char* NextBlock(char* footerEnd);
|
|
||||||
|
|
||||||
void installFooter(FooterAction* releaser, uint32_t padding);
|
|
||||||
void installUint32Footer(FooterAction* action, uint32_t value, uint32_t padding);
|
|
||||||
void installPtrFooter(FooterAction* action, char* ptr, uint32_t padding);
|
|
||||||
|
|
||||||
void ensureSpace(uint32_t size, uint32_t alignment);
|
|
||||||
|
|
||||||
char* allocObject(uint32_t size, uint32_t alignment) {
|
|
||||||
uintptr_t mask = alignment - 1;
|
|
||||||
uintptr_t alignedOffset = (~reinterpret_cast<uintptr_t>(fCursor) + 1) & mask;
|
|
||||||
uintptr_t totalSize = size + alignedOffset;
|
|
||||||
AssertRelease(totalSize >= size);
|
|
||||||
|
|
||||||
if (totalSize > static_cast<uintptr_t>(fEnd - fCursor)) {
|
|
||||||
this->ensureSpace(size, alignment);
|
|
||||||
alignedOffset = (~reinterpret_cast<uintptr_t>(fCursor) + 1) & mask;
|
|
||||||
}
|
|
||||||
return fCursor + alignedOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* allocObjectWithFooter(uint32_t sizeIncludingFooter, uint32_t alignment);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
char* commonArrayAlloc(uint32_t count) {
|
|
||||||
char* objStart;
|
|
||||||
AssertRelease(count <= std::numeric_limits<uint32_t>::max() / sizeof(T));
|
|
||||||
uint32_t arraySize = ToU32(count * sizeof(T));
|
|
||||||
uint32_t alignment = ToU32(alignof(T));
|
|
||||||
|
|
||||||
if (std::is_trivially_destructible<T>::value) {
|
|
||||||
objStart = this->allocObject(arraySize, alignment);
|
|
||||||
fCursor = objStart + arraySize;
|
|
||||||
} else {
|
|
||||||
constexpr uint32_t overhead = sizeof(Footer) + sizeof(uint32_t);
|
|
||||||
AssertRelease(arraySize <= std::numeric_limits<uint32_t>::max() - overhead);
|
|
||||||
uint32_t totalSize = arraySize + overhead;
|
|
||||||
objStart = this->allocObjectWithFooter(totalSize, alignment);
|
|
||||||
|
|
||||||
// Can never be UB because max value is alignof(T).
|
|
||||||
uint32_t padding = ToU32(objStart - fCursor);
|
|
||||||
|
|
||||||
// Advance to end of array to install footer.?
|
|
||||||
fCursor = objStart + arraySize;
|
|
||||||
this->installUint32Footer(
|
|
||||||
[](char* footerEnd) {
|
|
||||||
char* objEnd = footerEnd - (sizeof(Footer) + sizeof(uint32_t));
|
|
||||||
uint32_t count;
|
|
||||||
memmove(&count, objEnd, sizeof(uint32_t));
|
|
||||||
char* objStart = objEnd - count * sizeof(T);
|
|
||||||
T* array = (T*) objStart;
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
array[i].~T();
|
|
||||||
}
|
|
||||||
return objStart;
|
|
||||||
},
|
|
||||||
ToU32(count),
|
|
||||||
padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* fDtorCursor;
|
|
||||||
char* fCursor;
|
|
||||||
char* fEnd;
|
|
||||||
char* const fFirstBlock;
|
|
||||||
const uint32_t fFirstSize;
|
|
||||||
const uint32_t fFirstHeapAllocationSize;
|
|
||||||
|
|
||||||
// Use the Fibonacci sequence as the growth factor for block size. The size of the block
|
|
||||||
// allocated is fFib0 * fFirstHeapAllocationSize. Using 2 ^ n * fFirstHeapAllocationSize
|
|
||||||
// had too much slop for Android.
|
|
||||||
uint32_t fFib0 {1}, fFib1 {1};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper for defining allocators with inline/reserved storage.
|
|
||||||
// For argument declarations, stick to the base type (SkArenaAlloc).
|
|
||||||
template <size_t InlineStorageSize>
|
|
||||||
class VSTArenaAlloc : public VArenaAlloc {
|
|
||||||
public:
|
|
||||||
explicit VSTArenaAlloc(size_t firstHeapAllocation = InlineStorageSize)
|
|
||||||
: VArenaAlloc(fInlineStorage, InlineStorageSize, firstHeapAllocation) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
char fInlineStorage[InlineStorageSize];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VARENAALLOC_H
|
|
135
vendor/github.com/Benau/go_rlottie/vector_vbezier.cpp
generated
vendored
135
vendor/github.com/Benau/go_rlottie/vector_vbezier.cpp
generated
vendored
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vector_vbezier.h"
|
|
||||||
#include <cmath>
|
|
||||||
#include "vector_vline.h"
|
|
||||||
|
|
||||||
V_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
VBezier VBezier::fromPoints(const VPointF &p1, const VPointF &p2,
|
|
||||||
const VPointF &p3, const VPointF &p4)
|
|
||||||
{
|
|
||||||
VBezier b;
|
|
||||||
b.x1 = p1.x();
|
|
||||||
b.y1 = p1.y();
|
|
||||||
b.x2 = p2.x();
|
|
||||||
b.y2 = p2.y();
|
|
||||||
b.x3 = p3.x();
|
|
||||||
b.y3 = p3.y();
|
|
||||||
b.x4 = p4.x();
|
|
||||||
b.y4 = p4.y();
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
float VBezier::length() const
|
|
||||||
{
|
|
||||||
const auto len = VLine::length(x1, y1, x2, y2) +
|
|
||||||
VLine::length(x2, y2, x3, y3) +
|
|
||||||
VLine::length(x3, y3, x4, y4);
|
|
||||||
|
|
||||||
const auto chord = VLine::length(x1, y1, x4, y4);
|
|
||||||
|
|
||||||
if ((len - chord) > 0.01) {
|
|
||||||
VBezier left, right;
|
|
||||||
split(&left, &right);
|
|
||||||
return left.length() + right.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
VBezier VBezier::onInterval(float t0, float t1) const
|
|
||||||
{
|
|
||||||
if (t0 == 0 && t1 == 1) return *this;
|
|
||||||
|
|
||||||
VBezier bezier = *this;
|
|
||||||
|
|
||||||
VBezier result;
|
|
||||||
bezier.parameterSplitLeft(t0, &result);
|
|
||||||
float trueT = (t1 - t0) / (1 - t0);
|
|
||||||
bezier.parameterSplitLeft(trueT, &result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float VBezier::tAtLength(float l, float totalLength) const
|
|
||||||
{
|
|
||||||
float t = 1.0;
|
|
||||||
const float error = 0.01f;
|
|
||||||
if (l > totalLength || vCompare(l, totalLength)) return t;
|
|
||||||
|
|
||||||
t *= 0.5;
|
|
||||||
|
|
||||||
float lastBigger = 1.0;
|
|
||||||
for (int num = 0; num < 100500; num++) {
|
|
||||||
VBezier right = *this;
|
|
||||||
VBezier left;
|
|
||||||
right.parameterSplitLeft(t, &left);
|
|
||||||
float lLen = left.length();
|
|
||||||
if (fabs(lLen - l) < error) return t;
|
|
||||||
|
|
||||||
if (lLen < l) {
|
|
||||||
t += (lastBigger - t) * 0.5f;
|
|
||||||
} else {
|
|
||||||
lastBigger = t;
|
|
||||||
t -= t * 0.5f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vWarning << "no convergence";
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBezier::splitAtLength(float len, VBezier *left, VBezier *right)
|
|
||||||
{
|
|
||||||
float t;
|
|
||||||
|
|
||||||
*right = *this;
|
|
||||||
t = right->tAtLength(len);
|
|
||||||
right->parameterSplitLeft(t, left);
|
|
||||||
}
|
|
||||||
|
|
||||||
VPointF VBezier::derivative(float t) const
|
|
||||||
{
|
|
||||||
// p'(t) = 3 * (-(1-2t+t^2) * p0 + (1 - 4 * t + 3 * t^2) * p1 + (2 * t - 3 *
|
|
||||||
// t^2) * p2 + t^2 * p3)
|
|
||||||
|
|
||||||
float m_t = 1.0f - t;
|
|
||||||
|
|
||||||
float d = t * t;
|
|
||||||
float a = -m_t * m_t;
|
|
||||||
float b = 1 - 4 * t + 3 * d;
|
|
||||||
float c = 2 * t - 3 * d;
|
|
||||||
|
|
||||||
return 3 * VPointF(a * x1 + b * x2 + c * x3 + d * x4,
|
|
||||||
a * y1 + b * y2 + c * y3 + d * y4);
|
|
||||||
}
|
|
||||||
|
|
||||||
float VBezier::angleAt(float t) const
|
|
||||||
{
|
|
||||||
if (t < 0 || t > 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return VLine({}, derivative(t)).angle();
|
|
||||||
}
|
|
||||||
|
|
||||||
V_END_NAMESPACE
|
|
139
vendor/github.com/Benau/go_rlottie/vector_vbezier.h
generated
vendored
139
vendor/github.com/Benau/go_rlottie/vector_vbezier.h
generated
vendored
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VBEZIER_H
|
|
||||||
#define VBEZIER_H
|
|
||||||
|
|
||||||
#include "vector_vpoint.h"
|
|
||||||
|
|
||||||
V_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class VBezier {
|
|
||||||
public:
|
|
||||||
VBezier() = default;
|
|
||||||
VPointF pointAt(float t) const;
|
|
||||||
float angleAt(float t) const;
|
|
||||||
VBezier onInterval(float t0, float t1) const;
|
|
||||||
float length() const;
|
|
||||||
static void coefficients(float t, float &a, float &b, float &c, float &d);
|
|
||||||
static VBezier fromPoints(const VPointF &start, const VPointF &cp1,
|
|
||||||
const VPointF &cp2, const VPointF &end);
|
|
||||||
inline void parameterSplitLeft(float t, VBezier *left);
|
|
||||||
inline void split(VBezier *firstHalf, VBezier *secondHalf) const;
|
|
||||||
float tAtLength(float len) const { return tAtLength(len , length());}
|
|
||||||
float tAtLength(float len, float totalLength) const;
|
|
||||||
void splitAtLength(float len, VBezier *left, VBezier *right);
|
|
||||||
VPointF pt1() const { return {x1, y1}; }
|
|
||||||
VPointF pt2() const { return {x2, y2}; }
|
|
||||||
VPointF pt3() const { return {x3, y3}; }
|
|
||||||
VPointF pt4() const { return {x4, y4}; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
VPointF derivative(float t) const;
|
|
||||||
float x1, y1, x2, y2, x3, y3, x4, y4;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void VBezier::coefficients(float t, float &a, float &b, float &c,
|
|
||||||
float &d)
|
|
||||||
{
|
|
||||||
float m_t = 1.0f - t;
|
|
||||||
b = m_t * m_t;
|
|
||||||
c = t * t;
|
|
||||||
d = c * t;
|
|
||||||
a = b * m_t;
|
|
||||||
b *= 3.0f * t;
|
|
||||||
c *= 3.0f * m_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VPointF VBezier::pointAt(float t) const
|
|
||||||
{
|
|
||||||
// numerically more stable:
|
|
||||||
float x, y;
|
|
||||||
|
|
||||||
float m_t = 1.0f - t;
|
|
||||||
{
|
|
||||||
float a = x1 * m_t + x2 * t;
|
|
||||||
float b = x2 * m_t + x3 * t;
|
|
||||||
float c = x3 * m_t + x4 * t;
|
|
||||||
a = a * m_t + b * t;
|
|
||||||
b = b * m_t + c * t;
|
|
||||||
x = a * m_t + b * t;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
float a = y1 * m_t + y2 * t;
|
|
||||||
float b = y2 * m_t + y3 * t;
|
|
||||||
float c = y3 * m_t + y4 * t;
|
|
||||||
a = a * m_t + b * t;
|
|
||||||
b = b * m_t + c * t;
|
|
||||||
y = a * m_t + b * t;
|
|
||||||
}
|
|
||||||
return {x, y};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void VBezier::parameterSplitLeft(float t, VBezier *left)
|
|
||||||
{
|
|
||||||
left->x1 = x1;
|
|
||||||
left->y1 = y1;
|
|
||||||
|
|
||||||
left->x2 = x1 + t * (x2 - x1);
|
|
||||||
left->y2 = y1 + t * (y2 - y1);
|
|
||||||
|
|
||||||
left->x3 = x2 + t * (x3 - x2); // temporary holding spot
|
|
||||||
left->y3 = y2 + t * (y3 - y2); // temporary holding spot
|
|
||||||
|
|
||||||
x3 = x3 + t * (x4 - x3);
|
|
||||||
y3 = y3 + t * (y4 - y3);
|
|
||||||
|
|
||||||
x2 = left->x3 + t * (x3 - left->x3);
|
|
||||||
y2 = left->y3 + t * (y3 - left->y3);
|
|
||||||
|
|
||||||
left->x3 = left->x2 + t * (left->x3 - left->x2);
|
|
||||||
left->y3 = left->y2 + t * (left->y3 - left->y2);
|
|
||||||
|
|
||||||
left->x4 = x1 = left->x3 + t * (x2 - left->x3);
|
|
||||||
left->y4 = y1 = left->y3 + t * (y2 - left->y3);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void VBezier::split(VBezier *firstHalf, VBezier *secondHalf) const
|
|
||||||
{
|
|
||||||
float c = (x2 + x3) * 0.5f;
|
|
||||||
firstHalf->x2 = (x1 + x2) * 0.5f;
|
|
||||||
secondHalf->x3 = (x3 + x4) * 0.5f;
|
|
||||||
firstHalf->x1 = x1;
|
|
||||||
secondHalf->x4 = x4;
|
|
||||||
firstHalf->x3 = (firstHalf->x2 + c) * 0.5f;
|
|
||||||
secondHalf->x2 = (secondHalf->x3 + c) * 0.5f;
|
|
||||||
firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2) * 0.5f;
|
|
||||||
|
|
||||||
c = (y2 + y3) / 2;
|
|
||||||
firstHalf->y2 = (y1 + y2) * 0.5f;
|
|
||||||
secondHalf->y3 = (y3 + y4) * 0.5f;
|
|
||||||
firstHalf->y1 = y1;
|
|
||||||
secondHalf->y4 = y4;
|
|
||||||
firstHalf->y3 = (firstHalf->y2 + c) * 0.5f;
|
|
||||||
secondHalf->y2 = (secondHalf->y3 + c) * 0.5f;
|
|
||||||
firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2) * 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
V_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // VBEZIER_H
|
|
219
vendor/github.com/Benau/go_rlottie/vector_vbitmap.cpp
generated
vendored
219
vendor/github.com/Benau/go_rlottie/vector_vbitmap.cpp
generated
vendored
@ -1,219 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vector_vbitmap.h"
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include "vector_vdrawhelper.h"
|
|
||||||
#include "vector_vglobal.h"
|
|
||||||
|
|
||||||
V_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
void VBitmap::Impl::reset(size_t width, size_t height, VBitmap::Format format)
|
|
||||||
{
|
|
||||||
mRoData = nullptr;
|
|
||||||
mWidth = uint(width);
|
|
||||||
mHeight = uint(height);
|
|
||||||
mFormat = format;
|
|
||||||
|
|
||||||
mDepth = depth(format);
|
|
||||||
mStride = ((mWidth * mDepth + 31) >> 5)
|
|
||||||
<< 2; // bytes per scanline (must be multiple of 4)
|
|
||||||
mOwnData = std::make_unique<uchar[]>(mStride * mHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBitmap::Impl::reset(uchar *data, size_t width, size_t height, size_t bytesPerLine,
|
|
||||||
VBitmap::Format format)
|
|
||||||
{
|
|
||||||
mRoData = data;
|
|
||||||
mWidth = uint(width);
|
|
||||||
mHeight = uint(height);
|
|
||||||
mStride = uint(bytesPerLine);
|
|
||||||
mFormat = format;
|
|
||||||
mDepth = depth(format);
|
|
||||||
mOwnData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar VBitmap::Impl::depth(VBitmap::Format format)
|
|
||||||
{
|
|
||||||
uchar depth = 1;
|
|
||||||
switch (format) {
|
|
||||||
case VBitmap::Format::Alpha8:
|
|
||||||
depth = 8;
|
|
||||||
break;
|
|
||||||
case VBitmap::Format::ARGB32:
|
|
||||||
case VBitmap::Format::ARGB32_Premultiplied:
|
|
||||||
depth = 32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBitmap::Impl::fill(uint /*pixel*/)
|
|
||||||
{
|
|
||||||
//@TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBitmap::Impl::updateLuma()
|
|
||||||
{
|
|
||||||
if (mFormat != VBitmap::Format::ARGB32_Premultiplied) return;
|
|
||||||
auto dataPtr = data();
|
|
||||||
for (uint col = 0; col < mHeight; col++) {
|
|
||||||
uint *pixel = (uint *)(dataPtr + mStride * col);
|
|
||||||
for (uint row = 0; row < mWidth; row++) {
|
|
||||||
int alpha = vAlpha(*pixel);
|
|
||||||
if (alpha == 0) {
|
|
||||||
pixel++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int red = vRed(*pixel);
|
|
||||||
int green = vGreen(*pixel);
|
|
||||||
int blue = vBlue(*pixel);
|
|
||||||
|
|
||||||
if (alpha != 255) {
|
|
||||||
// un multiply
|
|
||||||
red = (red * 255) / alpha;
|
|
||||||
green = (green * 255) / alpha;
|
|
||||||
blue = (blue * 255) / alpha;
|
|
||||||
}
|
|
||||||
int luminosity = int(0.299f * red + 0.587f * green + 0.114f * blue);
|
|
||||||
*pixel = luminosity << 24;
|
|
||||||
pixel++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VBitmap::VBitmap(size_t width, size_t height, VBitmap::Format format)
|
|
||||||
{
|
|
||||||
if (width <= 0 || height <= 0 || format == Format::Invalid) return;
|
|
||||||
|
|
||||||
mImpl = rc_ptr<Impl>(width, height, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
VBitmap::VBitmap(uchar *data, size_t width, size_t height, size_t bytesPerLine,
|
|
||||||
VBitmap::Format format)
|
|
||||||
{
|
|
||||||
if (!data || width <= 0 || height <= 0 || bytesPerLine <= 0 ||
|
|
||||||
format == Format::Invalid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mImpl = rc_ptr<Impl>(data, width, height, bytesPerLine, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBitmap::reset(uchar *data, size_t w, size_t h, size_t bytesPerLine,
|
|
||||||
VBitmap::Format format)
|
|
||||||
{
|
|
||||||
if (mImpl) {
|
|
||||||
mImpl->reset(data, w, h, bytesPerLine, format);
|
|
||||||
} else {
|
|
||||||
mImpl = rc_ptr<Impl>(data, w, h, bytesPerLine, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBitmap::reset(size_t w, size_t h, VBitmap::Format format)
|
|
||||||
{
|
|
||||||
if (mImpl) {
|
|
||||||
if (w == mImpl->width() && h == mImpl->height() &&
|
|
||||||
format == mImpl->format()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mImpl->reset(w, h, format);
|
|
||||||
} else {
|
|
||||||
mImpl = rc_ptr<Impl>(w, h, format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t VBitmap::stride() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->stride() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t VBitmap::width() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->width() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t VBitmap::height() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->height() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t VBitmap::depth() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->mDepth : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar *VBitmap::data()
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->data() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar *VBitmap::data() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->data() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
VRect VBitmap::rect() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->rect() : VRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
VSize VBitmap::size() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->size() : VSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VBitmap::valid() const
|
|
||||||
{
|
|
||||||
return mImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
VBitmap::Format VBitmap::format() const
|
|
||||||
{
|
|
||||||
return mImpl ? mImpl->format() : VBitmap::Format::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VBitmap::fill(uint pixel)
|
|
||||||
{
|
|
||||||
if (mImpl) mImpl->fill(pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is special function which converts
|
|
||||||
* RGB value to Luminosity and stores it in
|
|
||||||
* the Alpha component of the pixel.
|
|
||||||
* After this conversion the bitmap data is no more
|
|
||||||
* in RGB space. but the Alpha component contains the
|
|
||||||
* Luminosity value of the pixel in HSL color space.
|
|
||||||
* NOTE: this api has its own special usecase
|
|
||||||
* make sure you know what you are doing before using
|
|
||||||
* this api.
|
|
||||||
*/
|
|
||||||
void VBitmap::updateLuma()
|
|
||||||
{
|
|
||||||
if (mImpl) mImpl->updateLuma();
|
|
||||||
}
|
|
||||||
|
|
||||||
V_END_NAMESPACE
|
|
94
vendor/github.com/Benau/go_rlottie/vector_vbitmap.h
generated
vendored
94
vendor/github.com/Benau/go_rlottie/vector_vbitmap.h
generated
vendored
@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VBITMAP_H
|
|
||||||
#define VBITMAP_H
|
|
||||||
|
|
||||||
#include "vector_vrect.h"
|
|
||||||
#include "vector_vsharedptr.h"
|
|
||||||
|
|
||||||
V_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class VBitmap {
|
|
||||||
public:
|
|
||||||
enum class Format: uchar {
|
|
||||||
Invalid,
|
|
||||||
Alpha8,
|
|
||||||
ARGB32,
|
|
||||||
ARGB32_Premultiplied
|
|
||||||
};
|
|
||||||
|
|
||||||
VBitmap() = default;
|
|
||||||
VBitmap(size_t w, size_t h, VBitmap::Format format);
|
|
||||||
VBitmap(uchar *data, size_t w, size_t h, size_t bytesPerLine, VBitmap::Format format);
|
|
||||||
void reset(uchar *data, size_t w, size_t h, size_t stride, VBitmap::Format format);
|
|
||||||
void reset(size_t w, size_t h, VBitmap::Format format=Format::ARGB32_Premultiplied);
|
|
||||||
size_t stride() const;
|
|
||||||
size_t width() const;
|
|
||||||
size_t height() const;
|
|
||||||
size_t depth() const;
|
|
||||||
VBitmap::Format format() const;
|
|
||||||
bool valid() const;
|
|
||||||
uchar * data();
|
|
||||||
uchar * data() const;
|
|
||||||
VRect rect() const;
|
|
||||||
VSize size() const;
|
|
||||||
void fill(uint pixel);
|
|
||||||
void updateLuma();
|
|
||||||
private:
|
|
||||||
struct Impl {
|
|
||||||
std::unique_ptr<uchar[]> mOwnData{nullptr};
|
|
||||||
uchar * mRoData{nullptr};
|
|
||||||
uint mWidth{0};
|
|
||||||
uint mHeight{0};
|
|
||||||
uint mStride{0};
|
|
||||||
uchar mDepth{0};
|
|
||||||
VBitmap::Format mFormat{VBitmap::Format::Invalid};
|
|
||||||
|
|
||||||
explicit Impl(size_t width, size_t height, VBitmap::Format format)
|
|
||||||
{
|
|
||||||
reset(width, height, format);
|
|
||||||
}
|
|
||||||
explicit Impl(uchar *data, size_t w, size_t h, size_t bytesPerLine, VBitmap::Format format)
|
|
||||||
{
|
|
||||||
reset(data, w, h, bytesPerLine, format);
|
|
||||||
}
|
|
||||||
VRect rect() const { return VRect(0, 0, mWidth, mHeight);}
|
|
||||||
VSize size() const { return VSize(mWidth, mHeight); }
|
|
||||||
size_t stride() const { return mStride; }
|
|
||||||
size_t width() const { return mWidth; }
|
|
||||||
size_t height() const { return mHeight; }
|
|
||||||
uchar * data() { return mRoData ? mRoData : mOwnData.get(); }
|
|
||||||
VBitmap::Format format() const { return mFormat; }
|
|
||||||
void reset(uchar *, size_t, size_t, size_t, VBitmap::Format);
|
|
||||||
void reset(size_t, size_t, VBitmap::Format);
|
|
||||||
static uchar depth(VBitmap::Format format);
|
|
||||||
void fill(uint);
|
|
||||||
void updateLuma();
|
|
||||||
};
|
|
||||||
|
|
||||||
rc_ptr<Impl> mImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
V_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // VBITMAP_H
|
|
69
vendor/github.com/Benau/go_rlottie/vector_vbrush.cpp
generated
vendored
69
vendor/github.com/Benau/go_rlottie/vector_vbrush.cpp
generated
vendored
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "vector_vbrush.h"
|
|
||||||
|
|
||||||
V_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
VGradient::VGradient(VGradient::Type type)
|
|
||||||
: mType(type)
|
|
||||||
{
|
|
||||||
if (mType == Type::Linear)
|
|
||||||
linear.x1 = linear.y1 = linear.x2 = linear.y2 = 0.0f;
|
|
||||||
else
|
|
||||||
radial.cx = radial.cy = radial.fx =
|
|
||||||
radial.fy = radial.cradius = radial.fradius = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VGradient::setStops(const VGradientStops &stops)
|
|
||||||
{
|
|
||||||
mStops = stops;
|
|
||||||
}
|
|
||||||
|
|
||||||
VBrush::VBrush(const VColor &color) : mType(VBrush::Type::Solid), mColor(color)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VBrush::VBrush(uchar r, uchar g, uchar b, uchar a)
|
|
||||||
: mType(VBrush::Type::Solid), mColor(r, g, b, a)
|
|
||||||
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VBrush::VBrush(const VGradient *gradient)
|
|
||||||
{
|
|
||||||
if (!gradient) return;
|
|
||||||
|
|
||||||
mGradient = gradient;
|
|
||||||
|
|
||||||
if (gradient->mType == VGradient::Type::Linear) {
|
|
||||||
mType = VBrush::Type::LinearGradient;
|
|
||||||
} else if (gradient->mType == VGradient::Type::Radial) {
|
|
||||||
mType = VBrush::Type::RadialGradient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VBrush::VBrush(const VTexture *texture):mType(VBrush::Type::Texture), mTexture(texture)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
V_END_NAMESPACE
|
|
92
vendor/github.com/Benau/go_rlottie/vector_vbrush.h
generated
vendored
92
vendor/github.com/Benau/go_rlottie/vector_vbrush.h
generated
vendored
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VBRUSH_H
|
|
||||||
#define VBRUSH_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "vector_vglobal.h"
|
|
||||||
#include "vector_vmatrix.h"
|
|
||||||
#include "vector_vpoint.h"
|
|
||||||
#include "vector_vbitmap.h"
|
|
||||||
|
|
||||||
V_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
using VGradientStop = std::pair<float, VColor>;
|
|
||||||
using VGradientStops = std::vector<VGradientStop>;
|
|
||||||
class VGradient {
|
|
||||||
public:
|
|
||||||
enum class Mode { Absolute, Relative };
|
|
||||||
enum class Spread { Pad, Repeat, Reflect };
|
|
||||||
enum class Type { Linear, Radial };
|
|
||||||
explicit VGradient(VGradient::Type type);
|
|
||||||
void setStops(const VGradientStops &stops);
|
|
||||||
void setAlpha(float alpha) {mAlpha = alpha;}
|
|
||||||
float alpha() const {return mAlpha;}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static constexpr int colorTableSize = 1024;
|
|
||||||
VGradient::Type mType{Type::Linear};
|
|
||||||
VGradient::Spread mSpread{Spread::Pad};
|
|
||||||
VGradient::Mode mMode{Mode::Absolute};
|
|
||||||
VGradientStops mStops;
|
|
||||||
float mAlpha{1.0};
|
|
||||||
struct Linear{
|
|
||||||
float x1{0}, y1{0}, x2{0}, y2{0};
|
|
||||||
};
|
|
||||||
struct Radial{
|
|
||||||
float cx{0}, cy{0}, fx{0}, fy{0}, cradius{0}, fradius{0};
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
Linear linear;
|
|
||||||
Radial radial;
|
|
||||||
};
|
|
||||||
VMatrix mMatrix;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VTexture {
|
|
||||||
VBitmap mBitmap;
|
|
||||||
VMatrix mMatrix;
|
|
||||||
int mAlpha{255};
|
|
||||||
};
|
|
||||||
|
|
||||||
class VBrush {
|
|
||||||
public:
|
|
||||||
enum class Type { NoBrush, Solid, LinearGradient, RadialGradient, Texture };
|
|
||||||
VBrush():mType(Type::NoBrush),mColor(){};
|
|
||||||
explicit VBrush(const VColor &color);
|
|
||||||
explicit VBrush(const VGradient *gradient);
|
|
||||||
explicit VBrush(uchar r, uchar g, uchar b, uchar a);
|
|
||||||
explicit VBrush(const VTexture *texture);
|
|
||||||
inline VBrush::Type type() const { return mType; }
|
|
||||||
public:
|
|
||||||
VBrush::Type mType{Type::NoBrush};
|
|
||||||
union {
|
|
||||||
VColor mColor{};
|
|
||||||
const VGradient *mGradient;
|
|
||||||
const VTexture *mTexture;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
V_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // VBRUSH_H
|
|
126
vendor/github.com/Benau/go_rlottie/vector_vcowptr.h
generated
vendored
126
vendor/github.com/Benau/go_rlottie/vector_vcowptr.h
generated
vendored
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VCOWPTR_H
|
|
||||||
#define VCOWPTR_H
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class vcow_ptr {
|
|
||||||
struct model {
|
|
||||||
std::atomic<std::size_t> mRef{1};
|
|
||||||
|
|
||||||
model() = default;
|
|
||||||
|
|
||||||
template <class... Args>
|
|
||||||
explicit model(Args&&... args) : mValue(std::forward<Args>(args)...){}
|
|
||||||
explicit model(const T& other) : mValue(other){}
|
|
||||||
|
|
||||||
T mValue;
|
|
||||||
};
|
|
||||||
model* mModel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using element_type = T;
|
|
||||||
|
|
||||||
vcow_ptr()
|
|
||||||
{
|
|
||||||
static model default_s;
|
|
||||||
mModel = &default_s;
|
|
||||||
++mModel->mRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
~vcow_ptr()
|
|
||||||
{
|
|
||||||
if (mModel && (--mModel->mRef == 0)) delete mModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Args>
|
|
||||||
explicit vcow_ptr(Args&&... args) : mModel(new model(std::forward<Args>(args)...))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
vcow_ptr(const vcow_ptr& x) noexcept : mModel(x.mModel)
|
|
||||||
{
|
|
||||||
assert(mModel);
|
|
||||||
++mModel->mRef;
|
|
||||||
}
|
|
||||||
vcow_ptr(vcow_ptr&& x) noexcept : mModel(x.mModel)
|
|
||||||
{
|
|
||||||
assert(mModel);
|
|
||||||
x.mModel = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator=(const vcow_ptr& x) noexcept -> vcow_ptr&
|
|
||||||
{
|
|
||||||
*this = vcow_ptr(x);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator=(vcow_ptr&& x) noexcept -> vcow_ptr&
|
|
||||||
{
|
|
||||||
auto tmp = std::move(x);
|
|
||||||
swap(*this, tmp);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator*() const noexcept -> const element_type& { return read(); }
|
|
||||||
|
|
||||||
auto operator-> () const noexcept -> const element_type* { return &read(); }
|
|
||||||
|
|
||||||
std::size_t refCount() const noexcept
|
|
||||||
{
|
|
||||||
assert(mModel);
|
|
||||||
|
|
||||||
return mModel->mRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool unique() const noexcept
|
|
||||||
{
|
|
||||||
assert(mModel);
|
|
||||||
|
|
||||||
return mModel->mRef == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto write() -> element_type&
|
|
||||||
{
|
|
||||||
if (!unique()) *this = vcow_ptr(read());
|
|
||||||
|
|
||||||
return mModel->mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto read() const noexcept -> const element_type&
|
|
||||||
{
|
|
||||||
assert(mModel);
|
|
||||||
|
|
||||||
return mModel->mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend inline void swap(vcow_ptr& x, vcow_ptr& y) noexcept
|
|
||||||
{
|
|
||||||
std::swap(x.mModel, y.mModel);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VCOWPTR_H
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user