提交 8a0d2451 编写于 作者: 3 3dgen

Merge branch 'master' of https://gitee.com/wa-lang/wa

......@@ -10,7 +10,7 @@ build-wasm:
GOARCH=wasm GOOS=js go build -o wa.out.wasm ./main_wasm.go
win-exe-icon:
windres -o main_rc_windows.syso main.rc
windres -o exe_rc_windows.syso exe.rc
arduino-run:
go run main.go -target=arduino arduino.wa
......
......@@ -40,11 +40,10 @@ func add(a: i32, b: i32) => i32 {
}
`
const code_zh = `// 版权 @2022 _examples/hello 作者。保留所有权利。
const code_zh = `
引于 "书"
【启】:
书·说:"你好,凹语言!"
书·说:"你好,凹语言中文版!"
`
......@@ -545,7 +545,7 @@ func Point.Length() => int {
return math.sqrt(this.x*this.x + this.y*this.y)
}
fn main {
func main {
p := Point{x:1, y:2}
println(p.Length())
}
......@@ -777,4 +777,4 @@ type duck interface {
届时就可以考虑给中文语法扩充更贴近中文用户使用习惯的特殊新语法了。
凹中文版的目标,不是让人人都用中文版语法、抛弃英文版语法,而是想抛砖引玉,启发所有人都来设计与开发更适合总国人的编程语言。
\ No newline at end of file
凹中文版的目标,不是让人人都用中文版语法、抛弃英文版语法,而是想抛砖引玉,启发所有人都来设计与开发更适合中国人的编程语言。
\ No newline at end of file
此差异已折叠。
......@@ -5,7 +5,6 @@ package app
import (
"fmt"
"os"
"strings"
"wa-lang.org/wa/internal/backends/compiler_wat"
"wa-lang.org/wa/internal/loader"
......@@ -21,22 +20,7 @@ func (p *App) WASM(filename string) ([]byte, error) {
return nil, err
}
// 凹中文的源码启动函数为【启】,对应的wat函数名应当是"$0xe590af"
main := "main"
if strings.HasSuffix(filename, ".wz") {
main = "$0xe590af"
}
// 如果是运行整个package,则判断主包里是否有名为【启】的函数,如果有,则将其作为启动函数
if filename == "." {
for k := range prog.SSAMainPkg.Members {
if k == "启" && prog.SSAMainPkg.Members[k].Type().Underlying().String() == "func()" {
main = "$0xe590af"
}
}
}
output, err := compiler_wat.New().Compile(prog, main)
output, err := compiler_wat.New().Compile(prog, "main")
if err != nil {
return nil, err
......
......@@ -2697,6 +2697,10 @@ func (p *parser) 解析函数定义() *ast.FuncDecl {
}
// p.expectSemi()
// 统一将【启】函数改名为【main】,注:其他函数不能直接调用【启】函数
if ident.Name == "启" {
ident.Name = "main"
}
decl := &ast.FuncDecl{
Doc: doc,
Recv: recv,
......
// 版权 @2023 凹语言 作者。保留所有权利。
// Package binary implements simple translation between numbers and byte
// sequences and encoding and decoding of varints.
//
// Numbers are translated by reading and writing fixed-size values.
// A fixed-size value is either a fixed-size arithmetic
// type (bool, int8, uint8, int16, float32, complex64, ...)
// or an array or struct containing only fixed-size values.
//
// The varint functions encode and decode single integer values using
// a variable-length encoding; smaller values require fewer bytes.
// For a specification, see
// https://developers.google.com/protocol-buffers/docs/encoding.
//
// This package favors simplicity over efficiency. Clients that require
// high-performance serialization, especially for large data structures,
// should look at more advanced solutions such as the encoding/gob
// package or protocol buffers.
import (
//"errors"
//"io"
//"math"
)
// A ByteOrder specifies how to convert byte sequences into
// 16-, 32-, or 64-bit unsigned integers.
type ByteOrder interface {
Uint16(b: []byte) => u16
Uint32(b: []byte) => u32
Uint64(b: []byte) => u64
PutUint16(b: []byte, v: u16)
PutUint32(b: []byte, v: u32)
PutUint64(b: []byte, v: u64)
String() => string
}
// LittleEndian is the little-endian implementation of ByteOrder.
var LittleEndian = &littleEndian{}
// BigEndian is the big-endian implementation of ByteOrder.
var BigEndian = &bigEndian{}
type littleEndian struct{}
func littleEndian.Uint16(b: []byte) => u16 {
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
return u16(b[0]) | u16(b[1])<<8
}
func littleEndian.PutUint16(b: []byte, v: u16) {
_ = b[1] // early bounds check to guarantee safety of writes below
b[0] = byte(v)
b[1] = byte(v >> 8)
}
func littleEndian.Uint32(b: []byte) => u32 {
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return u32(b[0]) | u32(b[1])<<8 | u32(b[2])<<16 | u32(b[3])<<24
}
func littleEndian.PutUint32(b: []byte, v: u32) {
_ = b[3] // early bounds check to guarantee safety of writes below
b[0] = byte(v)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
}
func littleEndian.Uint64(b: []byte) => u64 {
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return u64(b[0]) | u64(b[1])<<8 | u64(b[2])<<16 | u64(b[3])<<24 |
u64(b[4])<<32 | u64(b[5])<<40 | u64(b[6])<<48 | u64(b[7])<<56
}
func littleEndian.PutUint64(b: []byte, v: u64) {
_ = b[7] // early bounds check to guarantee safety of writes below
b[0] = byte(v)
b[1] = byte(v >> 8)
b[2] = byte(v >> 16)
b[3] = byte(v >> 24)
b[4] = byte(v >> 32)
b[5] = byte(v >> 40)
b[6] = byte(v >> 48)
b[7] = byte(v >> 56)
}
func littleEndian.String => string { return "LittleEndian" }
func littleEndian.WaString => string { return "binary.LittleEndian" }
type bigEndian struct{}
func bigEndian.Uint16(b: []byte) => u16 {
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
return u16(b[1]) | u16(b[0])<<8
}
func bigEndian.PutUint16(b: []byte, v: u16) {
_ = b[1] // early bounds check to guarantee safety of writes below
b[0] = byte(v >> 8)
b[1] = byte(v)
}
func bigEndian.Uint32(b: []byte) => u32 {
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return u32(b[3]) | u32(b[2])<<8 | u32(b[1])<<16 | u32(b[0])<<24
}
func bigEndian.PutUint32(b: []byte, v: u32) {
_ = b[3] // early bounds check to guarantee safety of writes below
b[0] = byte(v >> 24)
b[1] = byte(v >> 16)
b[2] = byte(v >> 8)
b[3] = byte(v)
}
func bigEndian.Uint64(b: []byte) => u64 {
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return u64(b[7]) | u64(b[6])<<8 | u64(b[5])<<16 | u64(b[4])<<24 |
u64(b[3])<<32 | u64(b[2])<<40 | u64(b[1])<<48 | u64(b[0])<<56
}
func bigEndian.PutUint64(b: []byte, v: u64) {
_ = b[7] // early bounds check to guarantee safety of writes below
b[0] = byte(v >> 56)
b[1] = byte(v >> 48)
b[2] = byte(v >> 40)
b[3] = byte(v >> 32)
b[4] = byte(v >> 24)
b[5] = byte(v >> 16)
b[6] = byte(v >> 8)
b[7] = byte(v)
}
func bigEndian.String => string { return "BigEndian" }
func bigEndian.WaString => string { return "binary.BigEndian" }
/*
// Read reads structured binary data from r into data.
// Data must be a pointer to a fixed-size value or a slice
// of fixed-size values.
// Bytes read from r are decoded using the specified byte order
// and written to successive fields of the data.
// When decoding boolean values, a zero byte is decoded as false, and
// any other non-zero byte is decoded as true.
// When reading into structs, the field data for fields with
// blank (_) field names is skipped; i.e., blank field names
// may be used for padding.
// When reading into a struct, all non-blank fields must be exported
// or Read may panic.
//
// The error is EOF only if no bytes were read.
// If an EOF happens after reading some but not all the bytes,
// Read returns ErrUnexpectedEOF.
func Read(r io.Reader, order ByteOrder, data interface{}) error {
// Fast path for basic types and slices.
if n := intDataSize(data); n != 0 {
bs := make([]byte, n)
if _, err := io.ReadFull(r, bs); err != nil {
return err
}
switch data := data.(type) {
case *bool:
*data = bs[0] != 0
case *int8:
*data = int8(bs[0])
case *uint8:
*data = bs[0]
case *int16:
*data = int16(order.Uint16(bs))
case *u16:
*data = order.Uint16(bs)
case *int32:
*data = int32(order.Uint32(bs))
case *u32:
*data = order.Uint32(bs)
case *int64:
*data = int64(order.Uint64(bs))
case *u64:
*data = order.Uint64(bs)
case *float32:
*data = math.Float32frombits(order.Uint32(bs))
case *float64:
*data = math.Float64frombits(order.Uint64(bs))
case []bool:
for i, x := range bs { // Easier to loop over the input for 8-bit values.
data[i] = x != 0
}
case []int8:
for i, x := range bs {
data[i] = int8(x)
}
case []uint8:
copy(data, bs)
case []int16:
for i := range data {
data[i] = int16(order.Uint16(bs[2*i:]))
}
case []u16:
for i := range data {
data[i] = order.Uint16(bs[2*i:])
}
case []int32:
for i := range data {
data[i] = int32(order.Uint32(bs[4*i:]))
}
case []u32:
for i := range data {
data[i] = order.Uint32(bs[4*i:])
}
case []int64:
for i := range data {
data[i] = int64(order.Uint64(bs[8*i:]))
}
case []u64:
for i := range data {
data[i] = order.Uint64(bs[8*i:])
}
case []float32:
for i := range data {
data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
}
case []float64:
for i := range data {
data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
}
default:
n = 0 // fast path doesn't apply
}
if n != 0 {
return nil
}
}
// Fallback to reflect-based decoding.
v := reflect.ValueOf(data)
size := -1
switch v.Kind() {
case reflect.Ptr:
v = v.Elem()
size = dataSize(v)
case reflect.Slice:
size = dataSize(v)
}
if size < 0 {
return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
}
d := &decoder{order: order, buf: make([]byte, size)}
if _, err := io.ReadFull(r, d.buf); err != nil {
return err
}
d.value(v)
return nil
}
// Write writes the binary representation of data into w.
// Data must be a fixed-size value or a slice of fixed-size
// values, or a pointer to such data.
// Boolean values encode as one byte: 1 for true, and 0 for false.
// Bytes written to w are encoded using the specified byte order
// and read from successive fields of the data.
// When writing structs, zero values are written for fields
// with blank (_) field names.
func Write(w io.Writer, order ByteOrder, data interface{}) error {
// Fast path for basic types and slices.
if n := intDataSize(data); n != 0 {
bs := make([]byte, n)
switch v := data.(type) {
case *bool:
if *v {
bs[0] = 1
} else {
bs[0] = 0
}
case bool:
if v {
bs[0] = 1
} else {
bs[0] = 0
}
case []bool:
for i, x := range v {
if x {
bs[i] = 1
} else {
bs[i] = 0
}
}
case *int8:
bs[0] = byte(*v)
case int8:
bs[0] = byte(v)
case []int8:
for i, x := range v {
bs[i] = byte(x)
}
case *uint8:
bs[0] = *v
case uint8:
bs[0] = v
case []uint8:
bs = v
case *int16:
order.PutUint16(bs, u16(*v))
case int16:
order.PutUint16(bs, u16(v))
case []int16:
for i, x := range v {
order.PutUint16(bs[2*i:], u16(x))
}
case *u16:
order.PutUint16(bs, *v)
case u16:
order.PutUint16(bs, v)
case []u16:
for i, x := range v {
order.PutUint16(bs[2*i:], x)
}
case *int32:
order.PutUint32(bs, u32(*v))
case int32:
order.PutUint32(bs, u32(v))
case []int32:
for i, x := range v {
order.PutUint32(bs[4*i:], u32(x))
}
case *u32:
order.PutUint32(bs, *v)
case u32:
order.PutUint32(bs, v)
case []u32:
for i, x := range v {
order.PutUint32(bs[4*i:], x)
}
case *int64:
order.PutUint64(bs, u64(*v))
case int64:
order.PutUint64(bs, u64(v))
case []int64:
for i, x := range v {
order.PutUint64(bs[8*i:], u64(x))
}
case *u64:
order.PutUint64(bs, *v)
case u64:
order.PutUint64(bs, v)
case []u64:
for i, x := range v {
order.PutUint64(bs[8*i:], x)
}
case *float32:
order.PutUint32(bs, math.Float32bits(*v))
case float32:
order.PutUint32(bs, math.Float32bits(v))
case []float32:
for i, x := range v {
order.PutUint32(bs[4*i:], math.Float32bits(x))
}
case *float64:
order.PutUint64(bs, math.Float64bits(*v))
case float64:
order.PutUint64(bs, math.Float64bits(v))
case []float64:
for i, x := range v {
order.PutUint64(bs[8*i:], math.Float64bits(x))
}
}
_, err := w.Write(bs)
return err
}
// Fallback to reflect-based encoding.
v := reflect.Indirect(reflect.ValueOf(data))
size := dataSize(v)
if size < 0 {
return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
}
buf := make([]byte, size)
e := &encoder{order: order, buf: buf}
e.value(v)
_, err := w.Write(buf)
return err
}
// Size returns how many bytes Write would generate to encode the value v, which
// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
// If v is neither of these, Size returns -1.
func Size(v interface{}) int {
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
}
var structSize sync.Map // map[reflect.Type]int
// dataSize returns the number of bytes the actual data represented by v occupies in memory.
// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
// it returns the length of the slice times the element size and does not count the memory
// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
func dataSize(v reflect.Value) int {
switch v.Kind() {
case reflect.Slice:
if s := sizeof(v.Type().Elem()); s >= 0 {
return s * v.Len()
}
return -1
case reflect.Struct:
t := v.Type()
if size, ok := structSize.Load(t); ok {
return size.(int)
}
size := sizeof(t)
structSize.Store(t, size)
return size
default:
return sizeof(v.Type())
}
}
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
func sizeof(t reflect.Type) int {
switch t.Kind() {
case reflect.Array:
if s := sizeof(t.Elem()); s >= 0 {
return s * t.Len()
}
case reflect.Struct:
sum := 0
for i, n := 0, t.NumField(); i < n; i++ {
s := sizeof(t.Field(i).Type)
if s < 0 {
return -1
}
sum += s
}
return sum
case reflect.Bool,
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
return int(t.Size())
}
return -1
}
type coder struct {
order ByteOrder
buf []byte
offset int
}
type decoder coder
type encoder coder
func (d *decoder) bool() bool {
x := d.buf[d.offset]
d.offset++
return x != 0
}
func (e *encoder) bool(x bool) {
if x {
e.buf[e.offset] = 1
} else {
e.buf[e.offset] = 0
}
e.offset++
}
func (d *decoder) uint8() uint8 {
x := d.buf[d.offset]
d.offset++
return x
}
func (e *encoder) uint8(x uint8) {
e.buf[e.offset] = x
e.offset++
}
func (d *decoder) u16() u16 {
x := d.order.Uint16(d.buf[d.offset : d.offset+2])
d.offset += 2
return x
}
func (e *encoder) u16(x u16) {
e.order.PutUint16(e.buf[e.offset:e.offset+2], x)
e.offset += 2
}
func (d *decoder) u32() u32 {
x := d.order.Uint32(d.buf[d.offset : d.offset+4])
d.offset += 4
return x
}
func (e *encoder) u32(x u32) {
e.order.PutUint32(e.buf[e.offset:e.offset+4], x)
e.offset += 4
}
func (d *decoder) u64() u64 {
x := d.order.Uint64(d.buf[d.offset : d.offset+8])
d.offset += 8
return x
}
func (e *encoder) u64(x u64) {
e.order.PutUint64(e.buf[e.offset:e.offset+8], x)
e.offset += 8
}
func (d *decoder) int8() int8 { return int8(d.uint8()) }
func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
func (d *decoder) int16() int16 { return int16(d.u16()) }
func (e *encoder) int16(x int16) { e.u16(u16(x)) }
func (d *decoder) int32() int32 { return int32(d.u32()) }
func (e *encoder) int32(x int32) { e.u32(u32(x)) }
func (d *decoder) int64() int64 { return int64(d.u64()) }
func (e *encoder) int64(x int64) { e.u64(u64(x)) }
func (d *decoder) value(v reflect.Value) {
switch v.Kind() {
case reflect.Array:
l := v.Len()
for i := 0; i < l; i++ {
d.value(v.Index(i))
}
case reflect.Struct:
t := v.Type()
l := v.NumField()
for i := 0; i < l; i++ {
// Note: Calling v.CanSet() below is an optimization.
// It would be sufficient to check the field name,
// but creating the StructField info for each field is
// costly (run "go test -bench=ReadStruct" and compare
// results when making changes to this code).
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
d.value(v)
} else {
d.skip(v)
}
}
case reflect.Slice:
l := v.Len()
for i := 0; i < l; i++ {
d.value(v.Index(i))
}
case reflect.Bool:
v.SetBool(d.bool())
case reflect.Int8:
v.SetInt(int64(d.int8()))
case reflect.Int16:
v.SetInt(int64(d.int16()))
case reflect.Int32:
v.SetInt(int64(d.int32()))
case reflect.Int64:
v.SetInt(d.int64())
case reflect.Uint8:
v.SetUint(u64(d.uint8()))
case reflect.Uint16:
v.SetUint(u64(d.u16()))
case reflect.Uint32:
v.SetUint(u64(d.u32()))
case reflect.Uint64:
v.SetUint(d.u64())
case reflect.Float32:
v.SetFloat(float64(math.Float32frombits(d.u32())))
case reflect.Float64:
v.SetFloat(math.Float64frombits(d.u64()))
case reflect.Complex64:
v.SetComplex(complex(
float64(math.Float32frombits(d.u32())),
float64(math.Float32frombits(d.u32())),
))
case reflect.Complex128:
v.SetComplex(complex(
math.Float64frombits(d.u64()),
math.Float64frombits(d.u64()),
))
}
}
func (e *encoder) value(v reflect.Value) {
switch v.Kind() {
case reflect.Array:
l := v.Len()
for i := 0; i < l; i++ {
e.value(v.Index(i))
}
case reflect.Struct:
t := v.Type()
l := v.NumField()
for i := 0; i < l; i++ {
// see comment for corresponding code in decoder.value()
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
e.value(v)
} else {
e.skip(v)
}
}
case reflect.Slice:
l := v.Len()
for i := 0; i < l; i++ {
e.value(v.Index(i))
}
case reflect.Bool:
e.bool(v.Bool())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch v.Type().Kind() {
case reflect.Int8:
e.int8(int8(v.Int()))
case reflect.Int16:
e.int16(int16(v.Int()))
case reflect.Int32:
e.int32(int32(v.Int()))
case reflect.Int64:
e.int64(v.Int())
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
switch v.Type().Kind() {
case reflect.Uint8:
e.uint8(uint8(v.Uint()))
case reflect.Uint16:
e.u16(u16(v.Uint()))
case reflect.Uint32:
e.u32(u32(v.Uint()))
case reflect.Uint64:
e.u64(v.Uint())
}
case reflect.Float32, reflect.Float64:
switch v.Type().Kind() {
case reflect.Float32:
e.u32(math.Float32bits(float32(v.Float())))
case reflect.Float64:
e.u64(math.Float64bits(v.Float()))
}
case reflect.Complex64, reflect.Complex128:
switch v.Type().Kind() {
case reflect.Complex64:
x := v.Complex()
e.u32(math.Float32bits(float32(real(x))))
e.u32(math.Float32bits(float32(imag(x))))
case reflect.Complex128:
x := v.Complex()
e.u64(math.Float64bits(real(x)))
e.u64(math.Float64bits(imag(x)))
}
}
}
func (d *decoder) skip(v reflect.Value) {
d.offset += dataSize(v)
}
func (e *encoder) skip(v reflect.Value) {
n := dataSize(v)
zero := e.buf[e.offset : e.offset+n]
for i := range zero {
zero[i] = 0
}
e.offset += n
}
// intDataSize returns the size of the data required to represent the data when encoded.
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
func intDataSize(data interface{}) int {
switch data := data.(type) {
case bool, int8, uint8, *bool, *int8, *uint8:
return 1
case []bool:
return len(data)
case []int8:
return len(data)
case []uint8:
return len(data)
case int16, u16, *int16, *u16:
return 2
case []int16:
return 2 * len(data)
case []u16:
return 2 * len(data)
case int32, u32, *int32, *u32:
return 4
case []int32:
return 4 * len(data)
case []u32:
return 4 * len(data)
case int64, u64, *int64, *u64:
return 8
case []int64:
return 8 * len(data)
case []u64:
return 8 * len(data)
case float32, *float32:
return 4
case float64, *float64:
return 8
case []float32:
return 4 * len(data)
case []float64:
return 8 * len(data)
}
return 0
}
*/
\ No newline at end of file
// 版权 @2023 凹语言 作者。保留所有权利。
import (
"errors"
//"image"
//"image/color"
//"io"
)
// ErrUnsupported means that the input BMP image uses a valid but unsupported
// feature.
var ErrUnsupported = errors.New("bmp: unsupported BMP image")
func readUint16(b: []byte) => uint16 {
return uint16(b[0]) | uint16(b[1])<<8
}
func readUint32(b: []byte) => uint32 {
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
/*
// decodeRGB reads a 24 bit-per-pixel BMP image from r.
// If topDown is false, the image rows will be read bottom-up.
func decodeRGB(r: io.Reader, c: image.Config, topDown: bool) => (m: image.Image, err: error) {
rgba := image.NewRGBA(image.Rect(0, 0, c.Width, c.Height))
if c.Width == 0 || c.Height == 0 {
return rgba, nil
}
// There are 3 bytes per pixel, and each row is 4-byte aligned.
b := make([]byte, (3*c.Width+3)&^3)
y0, y1, yDelta := c.Height-1, -1, -1
if topDown {
y0, y1, yDelta = 0, c.Height, +1
}
for y := y0; y != y1; y += yDelta {
if _, err := io.ReadFull(r, b); err != nil {
return nil, err
}
p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4]
for i, j := 0, 0; i < len(p); i, j = i+4, j+3 {
// BMP images are stored in BGR order rather than RGB order.
p[i+0] = b[j+2]
p[i+1] = b[j+1]
p[i+2] = b[j+0]
p[i+3] = 0xFF
}
}
return rgba, nil
}
// decodePaletted reads an 8 bit-per-pixel BMP image from r.
// If topDown is false, the image rows will be read bottom-up.
func decodePaletted(r: io.Reader, c: image.Config, topDown: bool) => (m: image.Image, err: error) {
paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette))
if c.Width == 0 || c.Height == 0 {
return paletted, nil
}
var tmp [4]byte
y0, y1, yDelta := c.Height-1, -1, -1
if topDown {
y0, y1, yDelta = 0, c.Height, +1
}
for y := y0; y != y1; y += yDelta {
p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width]
if _, err := io.ReadFull(r, p); err != nil {
return nil, err
}
// Each row is 4-byte aligned.
if c.Width%4 != 0 {
_, err := io.ReadFull(r, tmp[:4-c.Width%4])
if err != nil {
return nil, err
}
}
}
return paletted, nil
}
// decodeNRGBA reads a 32 bit-per-pixel BMP image from r.
// If topDown is false, the image rows will be read bottom-up.
func decodeNRGBA(r: io.Reader, c: image.Config, topDown, allowAlpha: bool) => (image.Image, error) {
rgba := image.NewNRGBA(image.Rect(0, 0, c.Width, c.Height))
if c.Width == 0 || c.Height == 0 {
return rgba, nil
}
y0, y1, yDelta := c.Height-1, -1, -1
if topDown {
y0, y1, yDelta = 0, c.Height, +1
}
for y := y0; y != y1; y += yDelta {
p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4]
if _, err := io.ReadFull(r, p); err != nil {
return nil, err
}
for i := 0; i < len(p); i += 4 {
// BMP images are stored in BGRA order rather than RGBA order.
p[i+0], p[i+2] = p[i+2], p[i+0]
if !allowAlpha {
p[i+3] = 0xFF
}
}
}
return rgba, nil
}
// Decode reads a BMP image from r and returns it as an image.Image.
// Limitation: The file must be 8, 24 or 32 bits per pixel.
func Decode(r io.Reader) (image.Image, error) {
c, bpp, topDown, allowAlpha, err := decodeConfig(r)
if err != nil {
return nil, err
}
switch bpp {
case 8:
return decodePaletted(r, c, topDown)
case 24:
return decodeRGB(r, c, topDown)
case 32:
return decodeNRGBA(r, c, topDown, allowAlpha)
}
panic("unreachable")
}
// DecodeConfig returns the color model and dimensions of a BMP image without
// decoding the entire image.
// Limitation: The file must be 8, 24 or 32 bits per pixel.
func DecodeConfig(r io.Reader) (image.Config, error) {
config, _, _, _, err := decodeConfig(r)
return config, err
}
func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown bool, allowAlpha bool, err error) {
// We only support those BMP images with one of the following DIB headers:
// - BITMAPINFOHEADER (40 bytes)
// - BITMAPV4HEADER (108 bytes)
// - BITMAPV5HEADER (124 bytes)
const (
fileHeaderLen = 14
infoHeaderLen = 40
v4InfoHeaderLen = 108
v5InfoHeaderLen = 124
)
var b [1024]byte
if _, err := io.ReadFull(r, b[:fileHeaderLen+4]); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
return image.Config{}, 0, false, false, err
}
if string(b[:2]) != "BM" {
return image.Config{}, 0, false, false, errors.New("bmp: invalid format")
}
offset := readUint32(b[10:14])
infoLen := readUint32(b[14:18])
if infoLen != infoHeaderLen && infoLen != v4InfoHeaderLen && infoLen != v5InfoHeaderLen {
return image.Config{}, 0, false, false, ErrUnsupported
}
if _, err := io.ReadFull(r, b[fileHeaderLen+4:fileHeaderLen+infoLen]); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
return image.Config{}, 0, false, false, err
}
width := int(int32(readUint32(b[18:22])))
height := int(int32(readUint32(b[22:26])))
if height < 0 {
height, topDown = -height, true
}
if width < 0 || height < 0 {
return image.Config{}, 0, false, false, ErrUnsupported
}
// We only support 1 plane and 8, 24 or 32 bits per pixel and no
// compression.
planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34])
// if compression is set to BI_BITFIELDS, but the bitmask is set to the default bitmask
// that would be used if compression was set to 0, we can continue as if compression was 0
if compression == 3 && infoLen > infoHeaderLen &&
readUint32(b[54:58]) == 0xff0000 && readUint32(b[58:62]) == 0xff00 &&
readUint32(b[62:66]) == 0xff && readUint32(b[66:70]) == 0xff000000 {
compression = 0
}
if planes != 1 || compression != 0 {
return image.Config{}, 0, false, false, ErrUnsupported
}
switch bpp {
case 8:
if offset != fileHeaderLen+infoLen+256*4 {
return image.Config{}, 0, false, false, ErrUnsupported
}
_, err = io.ReadFull(r, b[:256*4])
if err != nil {
return image.Config{}, 0, false, false, err
}
pcm := make(color.Palette, 256)
for i := range pcm {
// BMP images are stored in BGR order rather than RGB order.
// Every 4th byte is padding.
pcm[i] = color.RGBA{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF}
}
return image.Config{ColorModel: pcm, Width: width, Height: height}, 8, topDown, false, nil
case 24:
if offset != fileHeaderLen+infoLen {
return image.Config{}, 0, false, false, ErrUnsupported
}
return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 24, topDown, false, nil
case 32:
if offset != fileHeaderLen+infoLen {
return image.Config{}, 0, false, false, ErrUnsupported
}
// 32 bits per pixel is possibly RGBX (X is padding) or RGBA (A is
// alpha transparency). However, for BMP images, "Alpha is a
// poorly-documented and inconsistently-used feature" says
// https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc;l=621
//
// That goes on to say "BITMAPV3HEADER+ have an alpha bitmask in the
// info header... so we respect it at all times... [For earlier
// (smaller) headers we] ignore alpha in Windows V3 BMPs except inside
// ICO files".
//
// "Ignore" means to always set alpha to 0xFF (fully opaque):
// https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.h;l=272
//
// Confusingly, "Windows V3" does not correspond to BITMAPV3HEADER, but
// instead corresponds to the earlier (smaller) BITMAPINFOHEADER:
// https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc;l=258
//
// This Go package does not support ICO files and the (infoLen >
// infoHeaderLen) condition distinguishes BITMAPINFOHEADER (40 bytes)
// vs later (larger) headers.
allowAlpha = infoLen > infoHeaderLen
return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 32, topDown, allowAlpha, nil
}
return image.Config{}, 0, false, false, ErrUnsupported
}
*/
\ No newline at end of file
// 版权 @2023 凹语言 作者。保留所有权利。
// Color can convert itself to alpha-premultiplied 16-bits per channel RGBA.
// The conversion may be lossy.
type Color interface {
// RGBA returns the alpha-premultiplied red, green, blue and alpha values
// for the color. Each value ranges within [0, 0xffff], but is represented
// by a u32 so that multiplying by a blend factor up to 0xffff will not
// overflow.
//
// An alpha-premultiplied color component c has been scaled by alpha (a),
// so has valid values 0 <= c <= a.
RGBA() => (r, g, b, a: u32)
}
// RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
// bits for each of red, green, blue and alpha.
//
// An alpha-premultiplied color component C has been scaled by alpha (A), so
// has valid values 0 <= C <= A.
type RGBA struct {
R, G, B, A :u8
}
func RGBA.RGBA => (r, g, b, a :u32) {
r = u32(this.R)
r |= r << 8
g = u32(this.G)
g |= g << 8
b = u32(this.B)
b |= b << 8
a = u32(this.A)
a |= a << 8
return
}
// RGBA64 represents a 64-bit alpha-premultiplied color, having 16 bits for
// each of red, green, blue and alpha.
//
// An alpha-premultiplied color component C has been scaled by alpha (A), so
// has valid values 0 <= C <= A.
type RGBA64 struct {
R, G, B, A :u16
}
func RGBA64.RGBA => (r, g, b, a: u32) {
return u32(this.R), u32(this.G), u32(this.B), u32(this.A)
}
// NRGBA represents a non-alpha-premultiplied 32-bit color.
type NRGBA struct {
R, G, B, A :u8
}
func NRGBA.RGBA => (r, g, b, a :u32) {
r = u32(this.R)
r |= r << 8
r *= u32(this.A)
r /= 0xff
g = u32(this.G)
g |= g << 8
g *= u32(this.A)
g /= 0xff
b = u32(this.B)
b |= b << 8
b *= u32(this.A)
b /= 0xff
a = u32(this.A)
a |= a << 8
return
}
// NRGBA64 represents a non-alpha-premultiplied 64-bit color,
// having 16 bits for each of red, green, blue and alpha.
type NRGBA64 struct {
R, G, B, A :u16
}
func NRGBA64.RGBA => (r, g, b, a :u32) {
r = u32(this.R)
r *= u32(this.A)
r /= 0xffff
g = u32(this.G)
g *= u32(this.A)
g /= 0xffff
b = u32(this.B)
b *= u32(this.A)
b /= 0xffff
a = u32(this.A)
return
}
// Alpha represents an 8-bit alpha color.
type Alpha struct {
A :u8
}
func Alpha.RGBA => (r, g, b, a :u32) {
a = u32(this.A)
a |= a << 8
return a, a, a, a
}
// Alpha16 represents a 16-bit alpha color.
type Alpha16 struct {
A :u16
}
func Alpha16.RGBA => (r, g, b, a :u32) {
a = u32(this.A)
return a, a, a, a
}
// Gray represents an 8-bit grayscale color.
type Gray struct {
Y :u8
}
func Gray.RGBA => (r, g, b, a :u32) {
y := u32(this.Y)
y |= y << 8
return y, y, y, 0xffff
}
// Gray16 represents a 16-bit grayscale color.
type Gray16 struct {
Y :u16
}
func Gray16.RGBA => (r, g, b, a :u32) {
y := u32(this.Y)
return y, y, y, 0xffff
}
// Model can convert any Color to one from its own color model. The conversion
// may be lossy.
type Model interface {
Convert(c: Color) => Color
}
// ModelFunc returns a Model that invokes f to implement the conversion.
func ModelFunc(f: func(c: Color) => Color) => Model {
// Note: using *modelFunc as the implementation
// means that callers can still use comparisons
// like m == RGBAModel. This is not possible if
// we use the func value directly, because funcs
// are no longer comparable.
return &modelFunc{f}
}
type modelFunc struct {
f: func(Color) Color
}
func modelFunc.Convert(c: Color) => Color {
return this.f(c)
}
// Models for the standard color types.
var (
RGBAModel : Model = ModelFunc(rgbaModel)
RGBA64Model : Model = ModelFunc(rgba64Model)
NRGBAModel : Model = ModelFunc(nrgbaModel)
NRGBA64Model : Model = ModelFunc(nrgba64Model)
AlphaModel : Model = ModelFunc(alphaModel)
Alpha16Model : Model = ModelFunc(alpha16Model)
GrayModel : Model = ModelFunc(grayModel)
Gray16Model : Model = ModelFunc(gray16Model)
)
func rgbaModel(c: Color) => Color {
if _, ok := c.(*RGBA); ok {
return c
}
r, g, b, a := c.RGBA()
return &RGBA{u8(r >> 8), u8(g >> 8), u8(b >> 8), u8(a >> 8)}
}
func rgba64Model(c: Color) => Color {
if _, ok := c.(*RGBA64); ok {
return c
}
r, g, b, a := c.RGBA()
return &RGBA64{u16(r), u16(g), u16(b), u16(a)}
}
func nrgbaModel(c: Color) => Color {
if _, ok := c.(*NRGBA); ok {
return c
}
r, g, b, a := c.RGBA()
if a == 0xffff {
return &NRGBA{u8(r >> 8), u8(g >> 8), u8(b >> 8), 0xff}
}
if a == 0 {
return &NRGBA{0, 0, 0, 0}
}
// Since Color.RGBA returns an alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
r = (r * 0xffff) / a
g = (g * 0xffff) / a
b = (b * 0xffff) / a
return &NRGBA{u8(r >> 8), u8(g >> 8), u8(b >> 8), u8(a >> 8)}
}
func nrgba64Model(c: Color) => Color {
if _, ok := c.(*NRGBA64); ok {
return c
}
r, g, b, a := c.RGBA()
if a == 0xffff {
return &NRGBA64{u16(r), u16(g), u16(b), 0xffff}
}
if a == 0 {
return &NRGBA64{0, 0, 0, 0}
}
// Since Color.RGBA returns an alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
r = (r * 0xffff) / a
g = (g * 0xffff) / a
b = (b * 0xffff) / a
return &NRGBA64{u16(r), u16(g), u16(b), u16(a)}
}
func alphaModel(c: Color) => Color {
if _, ok := c.(*Alpha); ok {
return c
}
_, _, _, a := c.RGBA()
return &Alpha{u8(a >> 8)}
}
func alpha16Model(c: Color) => Color {
if _, ok := c.(*Alpha16); ok {
return c
}
_, _, _, a := c.RGBA()
return &Alpha16{u16(a)}
}
func grayModel(c: Color) => Color {
if _, ok := c.(*Gray); ok {
return c
}
r, g, b, _ := c.RGBA()
// These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
// as those given by the JFIF specification and used by func RGBToYCbCr in
// ycbcr.go.
//
// Note that 19595 + 38470 + 7471 equals 65536.
//
// The 24 is 16 + 8. The 16 is the same as used in RGBToYCbCr. The 8 is
// because the return value is 8 bit color, not 16 bit color.
y := (19595*r + 38470*g + 7471*b + 1<<15) >> 24
return &Gray{u8(y)}
}
func gray16Model(c: Color) => Color {
if _, ok := c.(*Gray16); ok {
return c
}
r, g, b, _ := c.RGBA()
// These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
// as those given by the JFIF specification and used by func RGBToYCbCr in
// ycbcr.go.
//
// Note that 19595 + 38470 + 7471 equals 65536.
y := (19595*r + 38470*g + 7471*b + 1<<15) >> 16
return &Gray16{u16(y)}
}
// Palette is a palette of colors.
type Palette: []Color
// Convert returns the palette color closest to c in Euclidean R,G,B space.
func Palette.Convert(c: Color) => Color {
if len(*this) == 0 {
return nil
}
return (*this)[this.Index(c)]
}
// Index returns the index of the palette color closest to c in Euclidean
// R,G,B,A space.
func Palette.Index(c: Color) => int {
// A batch version of this computation is in image/draw/draw.go.
cr, cg, cb, ca := c.RGBA()
ret, bestSum := 0, u32(1<<32-1)
for i, v := range *this {
vr, vg, vb, va := v.RGBA()
sum := sqDiff(cr, vr) + sqDiff(cg, vg) + sqDiff(cb, vb) + sqDiff(ca, va)
if sum < bestSum {
if sum == 0 {
return i
}
ret, bestSum = i, sum
}
}
return ret
}
// sqDiff returns the squared-difference of x and y, shifted by 2 so that
// adding four of those won't overflow a u32.
//
// x and y are both assumed to be in the range [0, 0xffff].
func sqDiff(x, y: u32) => u32 {
// The canonical code of this function looks as follows:
//
// var d u32
// if x > y {
// d = x - y
// } else {
// d = y - x
// }
// return (d * d) >> 2
//
// Language spec guarantees the following properties of unsigned integer
// values operations with respect to overflow/wrap around:
//
// > For unsigned integer values, the operations +, -, *, and << are
// > computed modulo 2n, where n is the bit width of the unsigned
// > integer's type. Loosely speaking, these unsigned integer operations
// > discard high bits upon overflow, and programs may rely on ``wrap
// > around''.
//
// Considering these properties and the fact that this function is
// called in the hot paths (x,y loops), it is reduced to the below code
// which is slightly faster. See TestSqDiff for correctness check.
d := x - y
return (d * d) >> 2
}
// Standard colors.
var (
Black = Gray16{0}
White = Gray16{0xffff}
Transparent = Alpha16{0}
Opaque = Alpha16{0xffff}
)
// 版权 @2023 凹语言 作者。保留所有权利。
//go:build ignore
// +build ignore
package main
// This program generates palette.wa. Invoke it as
// go run gen.go -output palette.wa
import (
"bytes"
"flag"
"fmt"
"go/format"
"io"
"log"
"os"
)
var filename = flag.String("output", "palette.wa", "output file name")
func main() {
flag.Parse()
var buf bytes.Buffer
fmt.Fprintln(&buf, `// 版权 @2023 凹语言 作者。保留所有权利。`)
fmt.Fprintln(&buf)
fmt.Fprintln(&buf, "// 由 go run gen.go -output palette.wa 命令自动生成; 不要手工修改")
fmt.Fprintln(&buf)
fmt.Fprintln(&buf, `import "image/color"`)
fmt.Fprintln(&buf)
printPlan9(&buf)
printWebSafe(&buf)
data, err := format.Source(buf.Bytes())
if err != nil {
log.Fatal(err)
}
err = os.WriteFile(*filename, data, 0644)
if err != nil {
log.Fatal(err)
}
}
func printPlan9(w io.Writer) {
c, lines := [3]int{}, [256]string{}
for r, i := 0, 0; r != 4; r++ {
for v := 0; v != 4; v, i = v+1, i+16 {
for g, j := 0, v-r; g != 4; g++ {
for b := 0; b != 4; b, j = b+1, j+1 {
den := r
if g > den {
den = g
}
if b > den {
den = b
}
if den == 0 {
c[0] = 0x11 * v
c[1] = 0x11 * v
c[2] = 0x11 * v
} else {
num := 17 * (4*den + v)
c[0] = r * num / den
c[1] = g * num / den
c[2] = b * num / den
}
lines[i+(j&0x0f)] =
fmt.Sprintf("\t&color.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", c[0], c[1], c[2])
}
}
}
}
fmt.Fprintln(w, "// Plan9 is a 256-color palette that partitions the 24-bit RGB space")
fmt.Fprintln(w, "// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the")
fmt.Fprintln(w, "// WebSafe, the idea is to reduce the color resolution by dicing the")
fmt.Fprintln(w, "// color cube into fewer cells, and to use the extra space to increase the")
fmt.Fprintln(w, "// intensity resolution. This results in 16 gray shades (4 gray subcubes with")
fmt.Fprintln(w, "// 4 samples in each), 13 shades of each primary and secondary color (3")
fmt.Fprintln(w, "// subcubes with 4 samples plus black) and a reasonable selection of colors")
fmt.Fprintln(w, "// covering the rest of the color cube. The advantage is better representation")
fmt.Fprintln(w, "// of continuous tones.")
fmt.Fprintln(w, "//")
fmt.Fprintln(w, "// This palette was used in the Plan 9 Operating System, described at")
fmt.Fprintln(w, "// https://9p.io/magic/man2html/6/color")
fmt.Fprintln(w, "var Plan9 = []color.Color{")
for _, line := range lines {
fmt.Fprintln(w, line)
}
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
}
func printWebSafe(w io.Writer) {
lines := [6 * 6 * 6]string{}
for r := 0; r < 6; r++ {
for g := 0; g < 6; g++ {
for b := 0; b < 6; b++ {
lines[36*r+6*g+b] =
fmt.Sprintf("\t&color.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", 0x33*r, 0x33*g, 0x33*b)
}
}
}
fmt.Fprintln(w, "// WebSafe is a 216-color palette that was popularized by early versions")
fmt.Fprintln(w, "// of Netscape Navigator. It is also known as the Netscape Color Cube.")
fmt.Fprintln(w, "//")
fmt.Fprintln(w, "// See https://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.")
fmt.Fprintln(w, "var WebSafe = []color.Color{")
for _, line := range lines {
fmt.Fprintln(w, line)
}
fmt.Fprintln(w, "}")
fmt.Fprintln(w)
}
// 版权 @2023 凹语言 作者。保留所有权利。
// 由 go run gen.go -output palette.wa 命令自动生成; 不要手工修改
import "image/color"
// Plan9 is a 256-color palette that partitions the 24-bit RGB space
// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the
// WebSafe, the idea is to reduce the color resolution by dicing the
// color cube into fewer cells, and to use the extra space to increase the
// intensity resolution. This results in 16 gray shades (4 gray subcubes with
// 4 samples in each), 13 shades of each primary and secondary color (3
// subcubes with 4 samples plus black) and a reasonable selection of colors
// covering the rest of the color cube. The advantage is better representation
// of continuous tones.
//
// This palette was used in the Plan 9 Operating System, described at
// https://9p.io/magic/man2html/6/color
var Plan9 = []color.Color{
&color.RGBA{0x00, 0x00, 0x00, 0xff},
&color.RGBA{0x00, 0x00, 0x44, 0xff},
&color.RGBA{0x00, 0x00, 0x88, 0xff},
&color.RGBA{0x00, 0x00, 0xcc, 0xff},
&color.RGBA{0x00, 0x44, 0x00, 0xff},
&color.RGBA{0x00, 0x44, 0x44, 0xff},
&color.RGBA{0x00, 0x44, 0x88, 0xff},
&color.RGBA{0x00, 0x44, 0xcc, 0xff},
&color.RGBA{0x00, 0x88, 0x00, 0xff},
&color.RGBA{0x00, 0x88, 0x44, 0xff},
&color.RGBA{0x00, 0x88, 0x88, 0xff},
&color.RGBA{0x00, 0x88, 0xcc, 0xff},
&color.RGBA{0x00, 0xcc, 0x00, 0xff},
&color.RGBA{0x00, 0xcc, 0x44, 0xff},
&color.RGBA{0x00, 0xcc, 0x88, 0xff},
&color.RGBA{0x00, 0xcc, 0xcc, 0xff},
&color.RGBA{0x00, 0xdd, 0xdd, 0xff},
&color.RGBA{0x11, 0x11, 0x11, 0xff},
&color.RGBA{0x00, 0x00, 0x55, 0xff},
&color.RGBA{0x00, 0x00, 0x99, 0xff},
&color.RGBA{0x00, 0x00, 0xdd, 0xff},
&color.RGBA{0x00, 0x55, 0x00, 0xff},
&color.RGBA{0x00, 0x55, 0x55, 0xff},
&color.RGBA{0x00, 0x4c, 0x99, 0xff},
&color.RGBA{0x00, 0x49, 0xdd, 0xff},
&color.RGBA{0x00, 0x99, 0x00, 0xff},
&color.RGBA{0x00, 0x99, 0x4c, 0xff},
&color.RGBA{0x00, 0x99, 0x99, 0xff},
&color.RGBA{0x00, 0x93, 0xdd, 0xff},
&color.RGBA{0x00, 0xdd, 0x00, 0xff},
&color.RGBA{0x00, 0xdd, 0x49, 0xff},
&color.RGBA{0x00, 0xdd, 0x93, 0xff},
&color.RGBA{0x00, 0xee, 0x9e, 0xff},
&color.RGBA{0x00, 0xee, 0xee, 0xff},
&color.RGBA{0x22, 0x22, 0x22, 0xff},
&color.RGBA{0x00, 0x00, 0x66, 0xff},
&color.RGBA{0x00, 0x00, 0xaa, 0xff},
&color.RGBA{0x00, 0x00, 0xee, 0xff},
&color.RGBA{0x00, 0x66, 0x00, 0xff},
&color.RGBA{0x00, 0x66, 0x66, 0xff},
&color.RGBA{0x00, 0x55, 0xaa, 0xff},
&color.RGBA{0x00, 0x4f, 0xee, 0xff},
&color.RGBA{0x00, 0xaa, 0x00, 0xff},
&color.RGBA{0x00, 0xaa, 0x55, 0xff},
&color.RGBA{0x00, 0xaa, 0xaa, 0xff},
&color.RGBA{0x00, 0x9e, 0xee, 0xff},
&color.RGBA{0x00, 0xee, 0x00, 0xff},
&color.RGBA{0x00, 0xee, 0x4f, 0xff},
&color.RGBA{0x00, 0xff, 0x55, 0xff},
&color.RGBA{0x00, 0xff, 0xaa, 0xff},
&color.RGBA{0x00, 0xff, 0xff, 0xff},
&color.RGBA{0x33, 0x33, 0x33, 0xff},
&color.RGBA{0x00, 0x00, 0x77, 0xff},
&color.RGBA{0x00, 0x00, 0xbb, 0xff},
&color.RGBA{0x00, 0x00, 0xff, 0xff},
&color.RGBA{0x00, 0x77, 0x00, 0xff},
&color.RGBA{0x00, 0x77, 0x77, 0xff},
&color.RGBA{0x00, 0x5d, 0xbb, 0xff},
&color.RGBA{0x00, 0x55, 0xff, 0xff},
&color.RGBA{0x00, 0xbb, 0x00, 0xff},
&color.RGBA{0x00, 0xbb, 0x5d, 0xff},
&color.RGBA{0x00, 0xbb, 0xbb, 0xff},
&color.RGBA{0x00, 0xaa, 0xff, 0xff},
&color.RGBA{0x00, 0xff, 0x00, 0xff},
&color.RGBA{0x44, 0x00, 0x44, 0xff},
&color.RGBA{0x44, 0x00, 0x88, 0xff},
&color.RGBA{0x44, 0x00, 0xcc, 0xff},
&color.RGBA{0x44, 0x44, 0x00, 0xff},
&color.RGBA{0x44, 0x44, 0x44, 0xff},
&color.RGBA{0x44, 0x44, 0x88, 0xff},
&color.RGBA{0x44, 0x44, 0xcc, 0xff},
&color.RGBA{0x44, 0x88, 0x00, 0xff},
&color.RGBA{0x44, 0x88, 0x44, 0xff},
&color.RGBA{0x44, 0x88, 0x88, 0xff},
&color.RGBA{0x44, 0x88, 0xcc, 0xff},
&color.RGBA{0x44, 0xcc, 0x00, 0xff},
&color.RGBA{0x44, 0xcc, 0x44, 0xff},
&color.RGBA{0x44, 0xcc, 0x88, 0xff},
&color.RGBA{0x44, 0xcc, 0xcc, 0xff},
&color.RGBA{0x44, 0x00, 0x00, 0xff},
&color.RGBA{0x55, 0x00, 0x00, 0xff},
&color.RGBA{0x55, 0x00, 0x55, 0xff},
&color.RGBA{0x4c, 0x00, 0x99, 0xff},
&color.RGBA{0x49, 0x00, 0xdd, 0xff},
&color.RGBA{0x55, 0x55, 0x00, 0xff},
&color.RGBA{0x55, 0x55, 0x55, 0xff},
&color.RGBA{0x4c, 0x4c, 0x99, 0xff},
&color.RGBA{0x49, 0x49, 0xdd, 0xff},
&color.RGBA{0x4c, 0x99, 0x00, 0xff},
&color.RGBA{0x4c, 0x99, 0x4c, 0xff},
&color.RGBA{0x4c, 0x99, 0x99, 0xff},
&color.RGBA{0x49, 0x93, 0xdd, 0xff},
&color.RGBA{0x49, 0xdd, 0x00, 0xff},
&color.RGBA{0x49, 0xdd, 0x49, 0xff},
&color.RGBA{0x49, 0xdd, 0x93, 0xff},
&color.RGBA{0x49, 0xdd, 0xdd, 0xff},
&color.RGBA{0x4f, 0xee, 0xee, 0xff},
&color.RGBA{0x66, 0x00, 0x00, 0xff},
&color.RGBA{0x66, 0x00, 0x66, 0xff},
&color.RGBA{0x55, 0x00, 0xaa, 0xff},
&color.RGBA{0x4f, 0x00, 0xee, 0xff},
&color.RGBA{0x66, 0x66, 0x00, 0xff},
&color.RGBA{0x66, 0x66, 0x66, 0xff},
&color.RGBA{0x55, 0x55, 0xaa, 0xff},
&color.RGBA{0x4f, 0x4f, 0xee, 0xff},
&color.RGBA{0x55, 0xaa, 0x00, 0xff},
&color.RGBA{0x55, 0xaa, 0x55, 0xff},
&color.RGBA{0x55, 0xaa, 0xaa, 0xff},
&color.RGBA{0x4f, 0x9e, 0xee, 0xff},
&color.RGBA{0x4f, 0xee, 0x00, 0xff},
&color.RGBA{0x4f, 0xee, 0x4f, 0xff},
&color.RGBA{0x4f, 0xee, 0x9e, 0xff},
&color.RGBA{0x55, 0xff, 0xaa, 0xff},
&color.RGBA{0x55, 0xff, 0xff, 0xff},
&color.RGBA{0x77, 0x00, 0x00, 0xff},
&color.RGBA{0x77, 0x00, 0x77, 0xff},
&color.RGBA{0x5d, 0x00, 0xbb, 0xff},
&color.RGBA{0x55, 0x00, 0xff, 0xff},
&color.RGBA{0x77, 0x77, 0x00, 0xff},
&color.RGBA{0x77, 0x77, 0x77, 0xff},
&color.RGBA{0x5d, 0x5d, 0xbb, 0xff},
&color.RGBA{0x55, 0x55, 0xff, 0xff},
&color.RGBA{0x5d, 0xbb, 0x00, 0xff},
&color.RGBA{0x5d, 0xbb, 0x5d, 0xff},
&color.RGBA{0x5d, 0xbb, 0xbb, 0xff},
&color.RGBA{0x55, 0xaa, 0xff, 0xff},
&color.RGBA{0x55, 0xff, 0x00, 0xff},
&color.RGBA{0x55, 0xff, 0x55, 0xff},
&color.RGBA{0x88, 0x00, 0x88, 0xff},
&color.RGBA{0x88, 0x00, 0xcc, 0xff},
&color.RGBA{0x88, 0x44, 0x00, 0xff},
&color.RGBA{0x88, 0x44, 0x44, 0xff},
&color.RGBA{0x88, 0x44, 0x88, 0xff},
&color.RGBA{0x88, 0x44, 0xcc, 0xff},
&color.RGBA{0x88, 0x88, 0x00, 0xff},
&color.RGBA{0x88, 0x88, 0x44, 0xff},
&color.RGBA{0x88, 0x88, 0x88, 0xff},
&color.RGBA{0x88, 0x88, 0xcc, 0xff},
&color.RGBA{0x88, 0xcc, 0x00, 0xff},
&color.RGBA{0x88, 0xcc, 0x44, 0xff},
&color.RGBA{0x88, 0xcc, 0x88, 0xff},
&color.RGBA{0x88, 0xcc, 0xcc, 0xff},
&color.RGBA{0x88, 0x00, 0x00, 0xff},
&color.RGBA{0x88, 0x00, 0x44, 0xff},
&color.RGBA{0x99, 0x00, 0x4c, 0xff},
&color.RGBA{0x99, 0x00, 0x99, 0xff},
&color.RGBA{0x93, 0x00, 0xdd, 0xff},
&color.RGBA{0x99, 0x4c, 0x00, 0xff},
&color.RGBA{0x99, 0x4c, 0x4c, 0xff},
&color.RGBA{0x99, 0x4c, 0x99, 0xff},
&color.RGBA{0x93, 0x49, 0xdd, 0xff},
&color.RGBA{0x99, 0x99, 0x00, 0xff},
&color.RGBA{0x99, 0x99, 0x4c, 0xff},
&color.RGBA{0x99, 0x99, 0x99, 0xff},
&color.RGBA{0x93, 0x93, 0xdd, 0xff},
&color.RGBA{0x93, 0xdd, 0x00, 0xff},
&color.RGBA{0x93, 0xdd, 0x49, 0xff},
&color.RGBA{0x93, 0xdd, 0x93, 0xff},
&color.RGBA{0x93, 0xdd, 0xdd, 0xff},
&color.RGBA{0x99, 0x00, 0x00, 0xff},
&color.RGBA{0xaa, 0x00, 0x00, 0xff},
&color.RGBA{0xaa, 0x00, 0x55, 0xff},
&color.RGBA{0xaa, 0x00, 0xaa, 0xff},
&color.RGBA{0x9e, 0x00, 0xee, 0xff},
&color.RGBA{0xaa, 0x55, 0x00, 0xff},
&color.RGBA{0xaa, 0x55, 0x55, 0xff},
&color.RGBA{0xaa, 0x55, 0xaa, 0xff},
&color.RGBA{0x9e, 0x4f, 0xee, 0xff},
&color.RGBA{0xaa, 0xaa, 0x00, 0xff},
&color.RGBA{0xaa, 0xaa, 0x55, 0xff},
&color.RGBA{0xaa, 0xaa, 0xaa, 0xff},
&color.RGBA{0x9e, 0x9e, 0xee, 0xff},
&color.RGBA{0x9e, 0xee, 0x00, 0xff},
&color.RGBA{0x9e, 0xee, 0x4f, 0xff},
&color.RGBA{0x9e, 0xee, 0x9e, 0xff},
&color.RGBA{0x9e, 0xee, 0xee, 0xff},
&color.RGBA{0xaa, 0xff, 0xff, 0xff},
&color.RGBA{0xbb, 0x00, 0x00, 0xff},
&color.RGBA{0xbb, 0x00, 0x5d, 0xff},
&color.RGBA{0xbb, 0x00, 0xbb, 0xff},
&color.RGBA{0xaa, 0x00, 0xff, 0xff},
&color.RGBA{0xbb, 0x5d, 0x00, 0xff},
&color.RGBA{0xbb, 0x5d, 0x5d, 0xff},
&color.RGBA{0xbb, 0x5d, 0xbb, 0xff},
&color.RGBA{0xaa, 0x55, 0xff, 0xff},
&color.RGBA{0xbb, 0xbb, 0x00, 0xff},
&color.RGBA{0xbb, 0xbb, 0x5d, 0xff},
&color.RGBA{0xbb, 0xbb, 0xbb, 0xff},
&color.RGBA{0xaa, 0xaa, 0xff, 0xff},
&color.RGBA{0xaa, 0xff, 0x00, 0xff},
&color.RGBA{0xaa, 0xff, 0x55, 0xff},
&color.RGBA{0xaa, 0xff, 0xaa, 0xff},
&color.RGBA{0xcc, 0x00, 0xcc, 0xff},
&color.RGBA{0xcc, 0x44, 0x00, 0xff},
&color.RGBA{0xcc, 0x44, 0x44, 0xff},
&color.RGBA{0xcc, 0x44, 0x88, 0xff},
&color.RGBA{0xcc, 0x44, 0xcc, 0xff},
&color.RGBA{0xcc, 0x88, 0x00, 0xff},
&color.RGBA{0xcc, 0x88, 0x44, 0xff},
&color.RGBA{0xcc, 0x88, 0x88, 0xff},
&color.RGBA{0xcc, 0x88, 0xcc, 0xff},
&color.RGBA{0xcc, 0xcc, 0x00, 0xff},
&color.RGBA{0xcc, 0xcc, 0x44, 0xff},
&color.RGBA{0xcc, 0xcc, 0x88, 0xff},
&color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
&color.RGBA{0xcc, 0x00, 0x00, 0xff},
&color.RGBA{0xcc, 0x00, 0x44, 0xff},
&color.RGBA{0xcc, 0x00, 0x88, 0xff},
&color.RGBA{0xdd, 0x00, 0x93, 0xff},
&color.RGBA{0xdd, 0x00, 0xdd, 0xff},
&color.RGBA{0xdd, 0x49, 0x00, 0xff},
&color.RGBA{0xdd, 0x49, 0x49, 0xff},
&color.RGBA{0xdd, 0x49, 0x93, 0xff},
&color.RGBA{0xdd, 0x49, 0xdd, 0xff},
&color.RGBA{0xdd, 0x93, 0x00, 0xff},
&color.RGBA{0xdd, 0x93, 0x49, 0xff},
&color.RGBA{0xdd, 0x93, 0x93, 0xff},
&color.RGBA{0xdd, 0x93, 0xdd, 0xff},
&color.RGBA{0xdd, 0xdd, 0x00, 0xff},
&color.RGBA{0xdd, 0xdd, 0x49, 0xff},
&color.RGBA{0xdd, 0xdd, 0x93, 0xff},
&color.RGBA{0xdd, 0xdd, 0xdd, 0xff},
&color.RGBA{0xdd, 0x00, 0x00, 0xff},
&color.RGBA{0xdd, 0x00, 0x49, 0xff},
&color.RGBA{0xee, 0x00, 0x4f, 0xff},
&color.RGBA{0xee, 0x00, 0x9e, 0xff},
&color.RGBA{0xee, 0x00, 0xee, 0xff},
&color.RGBA{0xee, 0x4f, 0x00, 0xff},
&color.RGBA{0xee, 0x4f, 0x4f, 0xff},
&color.RGBA{0xee, 0x4f, 0x9e, 0xff},
&color.RGBA{0xee, 0x4f, 0xee, 0xff},
&color.RGBA{0xee, 0x9e, 0x00, 0xff},
&color.RGBA{0xee, 0x9e, 0x4f, 0xff},
&color.RGBA{0xee, 0x9e, 0x9e, 0xff},
&color.RGBA{0xee, 0x9e, 0xee, 0xff},
&color.RGBA{0xee, 0xee, 0x00, 0xff},
&color.RGBA{0xee, 0xee, 0x4f, 0xff},
&color.RGBA{0xee, 0xee, 0x9e, 0xff},
&color.RGBA{0xee, 0xee, 0xee, 0xff},
&color.RGBA{0xee, 0x00, 0x00, 0xff},
&color.RGBA{0xff, 0x00, 0x00, 0xff},
&color.RGBA{0xff, 0x00, 0x55, 0xff},
&color.RGBA{0xff, 0x00, 0xaa, 0xff},
&color.RGBA{0xff, 0x00, 0xff, 0xff},
&color.RGBA{0xff, 0x55, 0x00, 0xff},
&color.RGBA{0xff, 0x55, 0x55, 0xff},
&color.RGBA{0xff, 0x55, 0xaa, 0xff},
&color.RGBA{0xff, 0x55, 0xff, 0xff},
&color.RGBA{0xff, 0xaa, 0x00, 0xff},
&color.RGBA{0xff, 0xaa, 0x55, 0xff},
&color.RGBA{0xff, 0xaa, 0xaa, 0xff},
&color.RGBA{0xff, 0xaa, 0xff, 0xff},
&color.RGBA{0xff, 0xff, 0x00, 0xff},
&color.RGBA{0xff, 0xff, 0x55, 0xff},
&color.RGBA{0xff, 0xff, 0xaa, 0xff},
&color.RGBA{0xff, 0xff, 0xff, 0xff},
}
// WebSafe is a 216-color palette that was popularized by early versions
// of Netscape Navigator. It is also known as the Netscape Color Cube.
//
// See https://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.
var WebSafe = []color.Color{
&color.RGBA{0x00, 0x00, 0x00, 0xff},
&color.RGBA{0x00, 0x00, 0x33, 0xff},
&color.RGBA{0x00, 0x00, 0x66, 0xff},
&color.RGBA{0x00, 0x00, 0x99, 0xff},
&color.RGBA{0x00, 0x00, 0xcc, 0xff},
&color.RGBA{0x00, 0x00, 0xff, 0xff},
&color.RGBA{0x00, 0x33, 0x00, 0xff},
&color.RGBA{0x00, 0x33, 0x33, 0xff},
&color.RGBA{0x00, 0x33, 0x66, 0xff},
&color.RGBA{0x00, 0x33, 0x99, 0xff},
&color.RGBA{0x00, 0x33, 0xcc, 0xff},
&color.RGBA{0x00, 0x33, 0xff, 0xff},
&color.RGBA{0x00, 0x66, 0x00, 0xff},
&color.RGBA{0x00, 0x66, 0x33, 0xff},
&color.RGBA{0x00, 0x66, 0x66, 0xff},
&color.RGBA{0x00, 0x66, 0x99, 0xff},
&color.RGBA{0x00, 0x66, 0xcc, 0xff},
&color.RGBA{0x00, 0x66, 0xff, 0xff},
&color.RGBA{0x00, 0x99, 0x00, 0xff},
&color.RGBA{0x00, 0x99, 0x33, 0xff},
&color.RGBA{0x00, 0x99, 0x66, 0xff},
&color.RGBA{0x00, 0x99, 0x99, 0xff},
&color.RGBA{0x00, 0x99, 0xcc, 0xff},
&color.RGBA{0x00, 0x99, 0xff, 0xff},
&color.RGBA{0x00, 0xcc, 0x00, 0xff},
&color.RGBA{0x00, 0xcc, 0x33, 0xff},
&color.RGBA{0x00, 0xcc, 0x66, 0xff},
&color.RGBA{0x00, 0xcc, 0x99, 0xff},
&color.RGBA{0x00, 0xcc, 0xcc, 0xff},
&color.RGBA{0x00, 0xcc, 0xff, 0xff},
&color.RGBA{0x00, 0xff, 0x00, 0xff},
&color.RGBA{0x00, 0xff, 0x33, 0xff},
&color.RGBA{0x00, 0xff, 0x66, 0xff},
&color.RGBA{0x00, 0xff, 0x99, 0xff},
&color.RGBA{0x00, 0xff, 0xcc, 0xff},
&color.RGBA{0x00, 0xff, 0xff, 0xff},
&color.RGBA{0x33, 0x00, 0x00, 0xff},
&color.RGBA{0x33, 0x00, 0x33, 0xff},
&color.RGBA{0x33, 0x00, 0x66, 0xff},
&color.RGBA{0x33, 0x00, 0x99, 0xff},
&color.RGBA{0x33, 0x00, 0xcc, 0xff},
&color.RGBA{0x33, 0x00, 0xff, 0xff},
&color.RGBA{0x33, 0x33, 0x00, 0xff},
&color.RGBA{0x33, 0x33, 0x33, 0xff},
&color.RGBA{0x33, 0x33, 0x66, 0xff},
&color.RGBA{0x33, 0x33, 0x99, 0xff},
&color.RGBA{0x33, 0x33, 0xcc, 0xff},
&color.RGBA{0x33, 0x33, 0xff, 0xff},
&color.RGBA{0x33, 0x66, 0x00, 0xff},
&color.RGBA{0x33, 0x66, 0x33, 0xff},
&color.RGBA{0x33, 0x66, 0x66, 0xff},
&color.RGBA{0x33, 0x66, 0x99, 0xff},
&color.RGBA{0x33, 0x66, 0xcc, 0xff},
&color.RGBA{0x33, 0x66, 0xff, 0xff},
&color.RGBA{0x33, 0x99, 0x00, 0xff},
&color.RGBA{0x33, 0x99, 0x33, 0xff},
&color.RGBA{0x33, 0x99, 0x66, 0xff},
&color.RGBA{0x33, 0x99, 0x99, 0xff},
&color.RGBA{0x33, 0x99, 0xcc, 0xff},
&color.RGBA{0x33, 0x99, 0xff, 0xff},
&color.RGBA{0x33, 0xcc, 0x00, 0xff},
&color.RGBA{0x33, 0xcc, 0x33, 0xff},
&color.RGBA{0x33, 0xcc, 0x66, 0xff},
&color.RGBA{0x33, 0xcc, 0x99, 0xff},
&color.RGBA{0x33, 0xcc, 0xcc, 0xff},
&color.RGBA{0x33, 0xcc, 0xff, 0xff},
&color.RGBA{0x33, 0xff, 0x00, 0xff},
&color.RGBA{0x33, 0xff, 0x33, 0xff},
&color.RGBA{0x33, 0xff, 0x66, 0xff},
&color.RGBA{0x33, 0xff, 0x99, 0xff},
&color.RGBA{0x33, 0xff, 0xcc, 0xff},
&color.RGBA{0x33, 0xff, 0xff, 0xff},
&color.RGBA{0x66, 0x00, 0x00, 0xff},
&color.RGBA{0x66, 0x00, 0x33, 0xff},
&color.RGBA{0x66, 0x00, 0x66, 0xff},
&color.RGBA{0x66, 0x00, 0x99, 0xff},
&color.RGBA{0x66, 0x00, 0xcc, 0xff},
&color.RGBA{0x66, 0x00, 0xff, 0xff},
&color.RGBA{0x66, 0x33, 0x00, 0xff},
&color.RGBA{0x66, 0x33, 0x33, 0xff},
&color.RGBA{0x66, 0x33, 0x66, 0xff},
&color.RGBA{0x66, 0x33, 0x99, 0xff},
&color.RGBA{0x66, 0x33, 0xcc, 0xff},
&color.RGBA{0x66, 0x33, 0xff, 0xff},
&color.RGBA{0x66, 0x66, 0x00, 0xff},
&color.RGBA{0x66, 0x66, 0x33, 0xff},
&color.RGBA{0x66, 0x66, 0x66, 0xff},
&color.RGBA{0x66, 0x66, 0x99, 0xff},
&color.RGBA{0x66, 0x66, 0xcc, 0xff},
&color.RGBA{0x66, 0x66, 0xff, 0xff},
&color.RGBA{0x66, 0x99, 0x00, 0xff},
&color.RGBA{0x66, 0x99, 0x33, 0xff},
&color.RGBA{0x66, 0x99, 0x66, 0xff},
&color.RGBA{0x66, 0x99, 0x99, 0xff},
&color.RGBA{0x66, 0x99, 0xcc, 0xff},
&color.RGBA{0x66, 0x99, 0xff, 0xff},
&color.RGBA{0x66, 0xcc, 0x00, 0xff},
&color.RGBA{0x66, 0xcc, 0x33, 0xff},
&color.RGBA{0x66, 0xcc, 0x66, 0xff},
&color.RGBA{0x66, 0xcc, 0x99, 0xff},
&color.RGBA{0x66, 0xcc, 0xcc, 0xff},
&color.RGBA{0x66, 0xcc, 0xff, 0xff},
&color.RGBA{0x66, 0xff, 0x00, 0xff},
&color.RGBA{0x66, 0xff, 0x33, 0xff},
&color.RGBA{0x66, 0xff, 0x66, 0xff},
&color.RGBA{0x66, 0xff, 0x99, 0xff},
&color.RGBA{0x66, 0xff, 0xcc, 0xff},
&color.RGBA{0x66, 0xff, 0xff, 0xff},
&color.RGBA{0x99, 0x00, 0x00, 0xff},
&color.RGBA{0x99, 0x00, 0x33, 0xff},
&color.RGBA{0x99, 0x00, 0x66, 0xff},
&color.RGBA{0x99, 0x00, 0x99, 0xff},
&color.RGBA{0x99, 0x00, 0xcc, 0xff},
&color.RGBA{0x99, 0x00, 0xff, 0xff},
&color.RGBA{0x99, 0x33, 0x00, 0xff},
&color.RGBA{0x99, 0x33, 0x33, 0xff},
&color.RGBA{0x99, 0x33, 0x66, 0xff},
&color.RGBA{0x99, 0x33, 0x99, 0xff},
&color.RGBA{0x99, 0x33, 0xcc, 0xff},
&color.RGBA{0x99, 0x33, 0xff, 0xff},
&color.RGBA{0x99, 0x66, 0x00, 0xff},
&color.RGBA{0x99, 0x66, 0x33, 0xff},
&color.RGBA{0x99, 0x66, 0x66, 0xff},
&color.RGBA{0x99, 0x66, 0x99, 0xff},
&color.RGBA{0x99, 0x66, 0xcc, 0xff},
&color.RGBA{0x99, 0x66, 0xff, 0xff},
&color.RGBA{0x99, 0x99, 0x00, 0xff},
&color.RGBA{0x99, 0x99, 0x33, 0xff},
&color.RGBA{0x99, 0x99, 0x66, 0xff},
&color.RGBA{0x99, 0x99, 0x99, 0xff},
&color.RGBA{0x99, 0x99, 0xcc, 0xff},
&color.RGBA{0x99, 0x99, 0xff, 0xff},
&color.RGBA{0x99, 0xcc, 0x00, 0xff},
&color.RGBA{0x99, 0xcc, 0x33, 0xff},
&color.RGBA{0x99, 0xcc, 0x66, 0xff},
&color.RGBA{0x99, 0xcc, 0x99, 0xff},
&color.RGBA{0x99, 0xcc, 0xcc, 0xff},
&color.RGBA{0x99, 0xcc, 0xff, 0xff},
&color.RGBA{0x99, 0xff, 0x00, 0xff},
&color.RGBA{0x99, 0xff, 0x33, 0xff},
&color.RGBA{0x99, 0xff, 0x66, 0xff},
&color.RGBA{0x99, 0xff, 0x99, 0xff},
&color.RGBA{0x99, 0xff, 0xcc, 0xff},
&color.RGBA{0x99, 0xff, 0xff, 0xff},
&color.RGBA{0xcc, 0x00, 0x00, 0xff},
&color.RGBA{0xcc, 0x00, 0x33, 0xff},
&color.RGBA{0xcc, 0x00, 0x66, 0xff},
&color.RGBA{0xcc, 0x00, 0x99, 0xff},
&color.RGBA{0xcc, 0x00, 0xcc, 0xff},
&color.RGBA{0xcc, 0x00, 0xff, 0xff},
&color.RGBA{0xcc, 0x33, 0x00, 0xff},
&color.RGBA{0xcc, 0x33, 0x33, 0xff},
&color.RGBA{0xcc, 0x33, 0x66, 0xff},
&color.RGBA{0xcc, 0x33, 0x99, 0xff},
&color.RGBA{0xcc, 0x33, 0xcc, 0xff},
&color.RGBA{0xcc, 0x33, 0xff, 0xff},
&color.RGBA{0xcc, 0x66, 0x00, 0xff},
&color.RGBA{0xcc, 0x66, 0x33, 0xff},
&color.RGBA{0xcc, 0x66, 0x66, 0xff},
&color.RGBA{0xcc, 0x66, 0x99, 0xff},
&color.RGBA{0xcc, 0x66, 0xcc, 0xff},
&color.RGBA{0xcc, 0x66, 0xff, 0xff},
&color.RGBA{0xcc, 0x99, 0x00, 0xff},
&color.RGBA{0xcc, 0x99, 0x33, 0xff},
&color.RGBA{0xcc, 0x99, 0x66, 0xff},
&color.RGBA{0xcc, 0x99, 0x99, 0xff},
&color.RGBA{0xcc, 0x99, 0xcc, 0xff},
&color.RGBA{0xcc, 0x99, 0xff, 0xff},
&color.RGBA{0xcc, 0xcc, 0x00, 0xff},
&color.RGBA{0xcc, 0xcc, 0x33, 0xff},
&color.RGBA{0xcc, 0xcc, 0x66, 0xff},
&color.RGBA{0xcc, 0xcc, 0x99, 0xff},
&color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
&color.RGBA{0xcc, 0xcc, 0xff, 0xff},
&color.RGBA{0xcc, 0xff, 0x00, 0xff},
&color.RGBA{0xcc, 0xff, 0x33, 0xff},
&color.RGBA{0xcc, 0xff, 0x66, 0xff},
&color.RGBA{0xcc, 0xff, 0x99, 0xff},
&color.RGBA{0xcc, 0xff, 0xcc, 0xff},
&color.RGBA{0xcc, 0xff, 0xff, 0xff},
&color.RGBA{0xff, 0x00, 0x00, 0xff},
&color.RGBA{0xff, 0x00, 0x33, 0xff},
&color.RGBA{0xff, 0x00, 0x66, 0xff},
&color.RGBA{0xff, 0x00, 0x99, 0xff},
&color.RGBA{0xff, 0x00, 0xcc, 0xff},
&color.RGBA{0xff, 0x00, 0xff, 0xff},
&color.RGBA{0xff, 0x33, 0x00, 0xff},
&color.RGBA{0xff, 0x33, 0x33, 0xff},
&color.RGBA{0xff, 0x33, 0x66, 0xff},
&color.RGBA{0xff, 0x33, 0x99, 0xff},
&color.RGBA{0xff, 0x33, 0xcc, 0xff},
&color.RGBA{0xff, 0x33, 0xff, 0xff},
&color.RGBA{0xff, 0x66, 0x00, 0xff},
&color.RGBA{0xff, 0x66, 0x33, 0xff},
&color.RGBA{0xff, 0x66, 0x66, 0xff},
&color.RGBA{0xff, 0x66, 0x99, 0xff},
&color.RGBA{0xff, 0x66, 0xcc, 0xff},
&color.RGBA{0xff, 0x66, 0xff, 0xff},
&color.RGBA{0xff, 0x99, 0x00, 0xff},
&color.RGBA{0xff, 0x99, 0x33, 0xff},
&color.RGBA{0xff, 0x99, 0x66, 0xff},
&color.RGBA{0xff, 0x99, 0x99, 0xff},
&color.RGBA{0xff, 0x99, 0xcc, 0xff},
&color.RGBA{0xff, 0x99, 0xff, 0xff},
&color.RGBA{0xff, 0xcc, 0x00, 0xff},
&color.RGBA{0xff, 0xcc, 0x33, 0xff},
&color.RGBA{0xff, 0xcc, 0x66, 0xff},
&color.RGBA{0xff, 0xcc, 0x99, 0xff},
&color.RGBA{0xff, 0xcc, 0xcc, 0xff},
&color.RGBA{0xff, 0xcc, 0xff, 0xff},
&color.RGBA{0xff, 0xff, 0x00, 0xff},
&color.RGBA{0xff, 0xff, 0x33, 0xff},
&color.RGBA{0xff, 0xff, 0x66, 0xff},
&color.RGBA{0xff, 0xff, 0x99, 0xff},
&color.RGBA{0xff, 0xff, 0xcc, 0xff},
&color.RGBA{0xff, 0xff, 0xff, 0xff},
}
// 版权 @2023 凹语言 作者。保留所有权利。
import (
//"image/color"
"strconv"
)
// A Point is an X, Y coordinate pair. The axes increase right and down.
type Point struct {
X, Y :int
}
// String returns a string representation of p like "(3,4)".
func Point.String => string {
return "(" + strconv.Itoa(this.X) + "," + strconv.Itoa(this.Y) + ")"
}
// Add returns the vector p+q.
func Point.Add(q :Point) => Point {
return Point{this.X + q.X, this.Y + q.Y}
}
// Sub returns the vector p-q.
func Point.Sub(q: Point) => Point {
return Point{this.X - q.X, this.Y - q.Y}
}
// Mul returns the vector p*k.
func Point.Mul(k: int) => Point {
return Point{this.X * k, this.Y * k}
}
// Div returns the vector p/k.
func Point.Div(k: int) => Point {
return Point{this.X / k, this.Y / k}
}
// In reports whether p is in r.
func Point.In(r: Rectangle) => bool {
return r.Min.X <= this.X && this.X < r.Max.X &&
r.Min.Y <= this.Y && this.Y < r.Max.Y
}
/*
// Mod returns the point q in r such that p.X-q.X is a multiple of r's width
// and p.Y-q.Y is a multiple of r's height.
func (p Point) Mod(r Rectangle) Point {
w, h := r.Dx(), r.Dy()
p = p.Sub(r.Min)
p.X = p.X % w
if p.X < 0 {
p.X += w
}
p.Y = p.Y % h
if p.Y < 0 {
p.Y += h
}
return p.Add(r.Min)
}
// Eq reports whether p and q are equal.
func (p Point) Eq(q Point) bool {
return p == q
}
// ZP is the zero Point.
//
// Deprecated: Use a literal image.Point{} instead.
var ZP Point
// Pt is shorthand for Point{X, Y}.
func Pt(X, Y int) Point {
return Point{X, Y}
}
*/
// A Rectangle contains the points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y.
// It is well-formed if Min.X <= Max.X and likewise for Y. Points are always
// well-formed. A rectangle's methods always return well-formed outputs for
// well-formed inputs.
//
// A Rectangle is also an Image whose bounds are the rectangle itself. At
// returns color.Opaque for points in the rectangle and color.Transparent
// otherwise.
type Rectangle struct {
Min, Max: Point
}
// String returns a string representation of r like "(3,4)-(6,5)".
func Rectangle.String => string {
return this.Min.String() + "-" + this.Max.String()
}
/*
// Dx returns r's width.
func (r Rectangle) Dx() int {
return r.Max.X - r.Min.X
}
// Dy returns r's height.
func (r Rectangle) Dy() int {
return r.Max.Y - r.Min.Y
}
// Size returns r's width and height.
func (r Rectangle) Size() Point {
return Point{
r.Max.X - r.Min.X,
r.Max.Y - r.Min.Y,
}
}
// Add returns the rectangle r translated by p.
func (r Rectangle) Add(p Point) Rectangle {
return Rectangle{
Point{r.Min.X + p.X, r.Min.Y + p.Y},
Point{r.Max.X + p.X, r.Max.Y + p.Y},
}
}
// Sub returns the rectangle r translated by -p.
func (r Rectangle) Sub(p Point) Rectangle {
return Rectangle{
Point{r.Min.X - p.X, r.Min.Y - p.Y},
Point{r.Max.X - p.X, r.Max.Y - p.Y},
}
}
// Inset returns the rectangle r inset by n, which may be negative. If either
// of r's dimensions is less than 2*n then an empty rectangle near the center
// of r will be returned.
func (r Rectangle) Inset(n int) Rectangle {
if r.Dx() < 2*n {
r.Min.X = (r.Min.X + r.Max.X) / 2
r.Max.X = r.Min.X
} else {
r.Min.X += n
r.Max.X -= n
}
if r.Dy() < 2*n {
r.Min.Y = (r.Min.Y + r.Max.Y) / 2
r.Max.Y = r.Min.Y
} else {
r.Min.Y += n
r.Max.Y -= n
}
return r
}
// Intersect returns the largest rectangle contained by both r and s. If the
// two rectangles do not overlap then the zero rectangle will be returned.
func (r Rectangle) Intersect(s Rectangle) Rectangle {
if r.Min.X < s.Min.X {
r.Min.X = s.Min.X
}
if r.Min.Y < s.Min.Y {
r.Min.Y = s.Min.Y
}
if r.Max.X > s.Max.X {
r.Max.X = s.Max.X
}
if r.Max.Y > s.Max.Y {
r.Max.Y = s.Max.Y
}
// Letting r0 and s0 be the values of r and s at the time that the method
// is called, this next line is equivalent to:
//
// if max(r0.Min.X, s0.Min.X) >= min(r0.Max.X, s0.Max.X) || likewiseForY { etc }
if r.Empty() {
return ZR
}
return r
}
// Union returns the smallest rectangle that contains both r and s.
func (r Rectangle) Union(s Rectangle) Rectangle {
if r.Empty() {
return s
}
if s.Empty() {
return r
}
if r.Min.X > s.Min.X {
r.Min.X = s.Min.X
}
if r.Min.Y > s.Min.Y {
r.Min.Y = s.Min.Y
}
if r.Max.X < s.Max.X {
r.Max.X = s.Max.X
}
if r.Max.Y < s.Max.Y {
r.Max.Y = s.Max.Y
}
return r
}
// Empty reports whether the rectangle contains no points.
func (r Rectangle) Empty() bool {
return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
}
// Eq reports whether r and s contain the same set of points. All empty
// rectangles are considered equal.
func (r Rectangle) Eq(s Rectangle) bool {
return r == s || r.Empty() && s.Empty()
}
// Overlaps reports whether r and s have a non-empty intersection.
func (r Rectangle) Overlaps(s Rectangle) bool {
return !r.Empty() && !s.Empty() &&
r.Min.X < s.Max.X && s.Min.X < r.Max.X &&
r.Min.Y < s.Max.Y && s.Min.Y < r.Max.Y
}
// In reports whether every point in r is in s.
func (r Rectangle) In(s Rectangle) bool {
if r.Empty() {
return true
}
// Note that r.Max is an exclusive bound for r, so that r.In(s)
// does not require that r.Max.In(s).
return s.Min.X <= r.Min.X && r.Max.X <= s.Max.X &&
s.Min.Y <= r.Min.Y && r.Max.Y <= s.Max.Y
}
// Canon returns the canonical version of r. The returned rectangle has minimum
// and maximum coordinates swapped if necessary so that it is well-formed.
func (r Rectangle) Canon() Rectangle {
if r.Max.X < r.Min.X {
r.Min.X, r.Max.X = r.Max.X, r.Min.X
}
if r.Max.Y < r.Min.Y {
r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
}
return r
}
// At implements the Image interface.
func (r Rectangle) At(x, y int) color.Color {
if (Point{x, y}).In(r) {
return color.Opaque
}
return color.Transparent
}
// RGBA64At implements the RGBA64Image interface.
func (r Rectangle) RGBA64At(x, y int) color.RGBA64 {
if (Point{x, y}).In(r) {
return color.RGBA64{0xffff, 0xffff, 0xffff, 0xffff}
}
return color.RGBA64{}
}
// Bounds implements the Image interface.
func (r Rectangle) Bounds() Rectangle {
return r
}
// ColorModel implements the Image interface.
func (r Rectangle) ColorModel() color.Model {
return color.Alpha16Model
}
// ZR is the zero Rectangle.
//
// Deprecated: Use a literal image.Rectangle{} instead.
var ZR Rectangle
// Rect is shorthand for Rectangle{Pt(x0, y0), Pt(x1, y1)}. The returned
// rectangle has minimum and maximum coordinates swapped if necessary so that
// it is well-formed.
func Rect(x0, y0, x1, y1 int) Rectangle {
if x0 > x1 {
x0, x1 = x1, x0
}
if y0 > y1 {
y0, y1 = y1, y0
}
return Rectangle{Point{x0, y0}, Point{x1, y1}}
}
// mul3NonNeg returns (x * y * z), unless at least one argument is negative or
// if the computation overflows the int type, in which case it returns -1.
func mul3NonNeg(x int, y int, z int) int {
if (x < 0) || (y < 0) || (z < 0) {
return -1
}
hi, lo := bits.Mul64(uint64(x), uint64(y))
if hi != 0 {
return -1
}
hi, lo = bits.Mul64(lo, uint64(z))
if hi != 0 {
return -1
}
a := int(lo)
if (a < 0) || (uint64(a) != lo) {
return -1
}
return a
}
// add2NonNeg returns (x + y), unless at least one argument is negative or if
// the computation overflows the int type, in which case it returns -1.
func add2NonNeg(x int, y int) int {
if (x < 0) || (y < 0) {
return -1
}
a := x + y
if a < 0 {
return -1
}
return a
}
*/
\ No newline at end of file
此差异已折叠。
// 版权 @2019 凹语言 作者。保留所有权利。
import "errors"
// Seek whence values.
const (
SeekStart = 0 // seek relative to the origin of the file
SeekCurrent = 1 // seek relative to the current offset
SeekEnd = 2 // seek relative to the end
)
// ErrShortWrite means that a write accepted fewer bytes than requested
// but failed to return an explicit error.
var ErrShortWrite = errors.New("short write")
// errInvalidWrite means that a write returned an impossible count.
var errInvalidWrite = errors.New("invalid write result")
// ErrShortBuffer means that a read required a longer buffer than was provided.
var ErrShortBuffer = errors.New("short buffer")
// EOF is the error returned by Read when no more input is available.
// (Read must return EOF itself, not an error wrapping EOF,
// because callers will test for EOF using ==.)
// Functions should return EOF only to signal a graceful end of input.
// If the EOF occurs unexpectedly in a structured data stream,
// the appropriate error is either ErrUnexpectedEOF or some other error
// giving more detail.
var EOF = errors.New("EOF")
// ErrUnexpectedEOF means that EOF was encountered in the
// middle of reading a fixed-size block or data structure.
var ErrUnexpectedEOF = errors.New("unexpected EOF")
// ErrNoProgress is returned by some clients of an Reader when
// many calls to Read have failed to return any data or error,
// usually the sign of a broken Reader implementation.
var ErrNoProgress = errors.New("multiple Read calls return no data or error")
// Reader is the interface that wraps the basic Read method.
//
// Read reads up to len(p) bytes into p. It returns the number of bytes
// read (0 <= n <= len(p)) and any error encountered. Even if Read
// returns n < len(p), it may use all of p as scratch space during the call.
// If some data is available but not len(p) bytes, Read conventionally
// returns what is available instead of waiting for more.
//
// When Read encounters an error or end-of-file condition after
// successfully reading n > 0 bytes, it returns the number of
// bytes read. It may return the (non-nil) error from the same call
// or return the error (and n == 0) from a subsequent call.
// An instance of this general case is that a Reader returning
// a non-zero number of bytes at the end of the input stream may
// return either err == EOF or err == nil. The next Read should
// return 0, EOF.
//
// Callers should always process the n > 0 bytes returned before
// considering the error err. Doing so correctly handles I/O errors
// that happen after reading some bytes and also both of the
// allowed EOF behaviors.
//
// Implementations of Read are discouraged from returning a
// zero byte count with a nil error, except when len(p) == 0.
// Callers should treat a return of 0 and nil as indicating that
// nothing happened; in particular it does not indicate EOF.
//
// Implementations must not retain p.
type Reader interface {
Read(p: []byte) => (n: int, err: error)
}
// Writer is the interface that wraps the basic Write method.
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// Write must return a non-nil error if it returns n < len(p).
// Write must not modify the slice data, even temporarily.
//
// Implementations must not retain p.
type Writer interface {
Write(p: []byte) => (n: int, err: error)
}
// Closer is the interface that wraps the basic Close method.
//
// The behavior of Close after the first call is undefined.
// Specific implementations may document their own behavior.
type Closer interface {
Close() => error
}
// Seeker is the interface that wraps the basic Seek method.
//
// Seek sets the offset for the next Read or Write to offset,
// interpreted according to whence:
// SeekStart means relative to the start of the file,
// SeekCurrent means relative to the current offset, and
// SeekEnd means relative to the end.
// Seek returns the new offset relative to the start of the
// file and an error, if any.
//
// Seeking to an offset before the start of the file is an error.
// Seeking to any positive offset is legal, but the behavior of subsequent
// I/O operations on the underlying object is implementation-dependent.
type Seeker interface {
Seek(offset: i64, whence: int) => (i64, error)
}
// ReadWriter is the interface that groups the basic Read and Write methods.
type ReadWriter interface {
Reader
Writer
}
// ReadCloser is the interface that groups the basic Read and Close methods.
type ReadCloser interface {
Reader
Closer
}
// WriteCloser is the interface that groups the basic Write and Close methods.
type WriteCloser interface {
Writer
Closer
}
// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
type ReadWriteCloser interface {
Reader
Writer
Closer
}
// ReadSeeker is the interface that groups the basic Read and Seek methods.
type ReadSeeker interface {
Reader
Seeker
}
// ReadSeekCloser is the interface that groups the basic Read, Seek and Close
// methods.
type ReadSeekCloser interface {
Reader
Seeker
Closer
}
// WriteSeeker is the interface that groups the basic Write and Seek methods.
type WriteSeeker interface {
Writer
Seeker
}
// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
type ReadWriteSeeker interface {
Reader
Writer
Seeker
}
// ReaderFrom is the interface that wraps the ReadFrom method.
//
// ReadFrom reads data from r until EOF or error.
// The return value n is the number of bytes read.
// Any error except EOF encountered during the read is also returned.
//
// The Copy function uses ReaderFrom if available.
type ReaderFrom interface {
ReadFrom(r: Reader) => (n: int64, err: error)
}
// WriterTo is the interface that wraps the WriteTo method.
//
// WriteTo writes data to w until there's no more data to write or
// when an error occurs. The return value n is the number of bytes
// written. Any error encountered during the write is also returned.
//
// The Copy function uses WriterTo if available.
type WriterTo interface {
WriteTo(w: Writer) => (n: i64, err: error)
}
// ReaderAt is the interface that wraps the basic ReadAt method.
//
// ReadAt reads len(p) bytes into p starting at offset off in the
// underlying input source. It returns the number of bytes
// read (0 <= n <= len(p)) and any error encountered.
//
// When ReadAt returns n < len(p), it returns a non-nil error
// explaining why more bytes were not returned. In this respect,
// ReadAt is stricter than Read.
//
// Even if ReadAt returns n < len(p), it may use all of p as scratch
// space during the call. If some data is available but not len(p) bytes,
// ReadAt blocks until either all the data is available or an error occurs.
// In this respect ReadAt is different from Read.
//
// If the n = len(p) bytes returned by ReadAt are at the end of the
// input source, ReadAt may return either err == EOF or err == nil.
//
// If ReadAt is reading from an input source with a seek offset,
// ReadAt should not affect nor be affected by the underlying
// seek offset.
//
// Clients of ReadAt can execute parallel ReadAt calls on the
// same input source.
//
// Implementations must not retain p.
type ReaderAt interface {
ReadAt(p: []byte, off: i64) => (n: int, err: error)
}
// WriterAt is the interface that wraps the basic WriteAt method.
//
// WriteAt writes len(p) bytes from p to the underlying data stream
// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// WriteAt must return a non-nil error if it returns n < len(p).
//
// If WriteAt is writing to a destination with a seek offset,
// WriteAt should not affect nor be affected by the underlying
// seek offset.
//
// Clients of WriteAt can execute parallel WriteAt calls on the same
// destination if the ranges do not overlap.
//
// Implementations must not retain p.
type WriterAt interface {
WriteAt(p: []byte, off: i64) => (n: int, err: error)
}
// ByteReader is the interface that wraps the ReadByte method.
//
// ReadByte reads and returns the next byte from the input or
// any error encountered. If ReadByte returns an error, no input
// byte was consumed, and the returned byte value is undefined.
//
// ReadByte provides an efficient interface for byte-at-time
// processing. A Reader that does not implement ByteReader
// can be wrapped using bufio.NewReader to add this method.
type ByteReader interface {
ReadByte() => (byte, error)
}
// ByteScanner is the interface that adds the UnreadByte method to the
// basic ReadByte method.
//
// UnreadByte causes the next call to ReadByte to return the same byte
// as the previous call to ReadByte.
// It may be an error to call UnreadByte twice without an intervening
// call to ReadByte.
type ByteScanner interface {
ByteReader
UnreadByte() => error
}
// ByteWriter is the interface that wraps the WriteByte method.
type ByteWriter interface {
WriteByte(c: byte) => error
}
// RuneReader is the interface that wraps the ReadRune method.
//
// ReadRune reads a single UTF-8 encoded Unicode character
// and returns the rune and its size in bytes. If no character is
// available, err will be set.
type RuneReader interface {
ReadRune() => (r: rune, size: int, err: error)
}
// RuneScanner is the interface that adds the UnreadRune method to the
// basic ReadRune method.
//
// UnreadRune causes the next call to ReadRune to return the same rune
// as the previous call to ReadRune.
// It may be an error to call UnreadRune twice without an intervening
// call to ReadRune.
type RuneScanner interface {
RuneReader
UnreadRune() => error
}
// StringWriter is the interface that wraps the WriteString method.
type StringWriter interface {
WriteString(s: string) => (n: int, err: error)
}
// WriteString writes the contents of the string s to w, which accepts a slice of bytes.
// If w implements StringWriter, its WriteString method is invoked directly.
// Otherwise, w.Write is called exactly once.
func WriteString(w: Writer, s: string) => (n: int, err: error) {
if sw, ok := w.(StringWriter); ok {
return sw.WriteString(s)
}
return w.Write([]byte(s))
}
// ReadAtLeast reads from r into buf until it has read at least min bytes.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is EOF only if no bytes were read.
// If an EOF happens after reading fewer than min bytes,
// ReadAtLeast returns ErrUnexpectedEOF.
// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
// On return, n >= min if and only if err == nil.
// If r returns an error having read at least min bytes, the error is dropped.
func ReadAtLeast(r: Reader, buf: []byte, min: int) => (n: int, err: error) {
if len(buf) < min {
return 0, ErrShortBuffer
}
for n < min && err == nil {
var nn :int
nn, err = r.Read(buf[n:])
n += nn
}
if n >= min {
err = nil
} else if n > 0 && err == EOF {
err = ErrUnexpectedEOF
}
return
}
// ReadFull reads exactly len(buf) bytes from r into buf.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is EOF only if no bytes were read.
// If an EOF happens after reading some but not all the bytes,
// ReadFull returns ErrUnexpectedEOF.
// On return, n == len(buf) if and only if err == nil.
// If r returns an error having read at least len(buf) bytes, the error is dropped.
func ReadFull(r: Reader, buf: []byte) => (n: int, err: error) {
return ReadAtLeast(r, buf, len(buf))
}
// CopyN copies n bytes (or until an error) from src to dst.
// It returns the number of bytes copied and the earliest
// error encountered while copying.
// On return, written == n if and only if err == nil.
//
// If dst implements the ReaderFrom interface,
// the copy is implemented using it.
func CopyN(dst: Writer, src: Reader, n: i64) => (written: i64, err: error) {
written, err = Copy(dst, LimitReader(src, n))
if written == n {
return n, nil
}
if written < n && err == nil {
// src stopped early; must have been EOF.
err = EOF
}
return
}
// Copy copies from src to dst until either EOF is reached
// on src or an error occurs. It returns the number of bytes
// copied and the first error encountered while copying, if any.
//
// A successful Copy returns err == nil, not err == EOF.
// Because Copy is defined to read from src until EOF, it does
// not treat an EOF from Read as an error to be reported.
//
// If src implements the WriterTo interface,
// the copy is implemented by calling src.WriteTo(dst).
// Otherwise, if dst implements the ReaderFrom interface,
// the copy is implemented by calling dst.ReadFrom(src).
func Copy(dst: Writer, src: Reader) => (written: i64, err: error) {
return copyBuffer(dst, src, nil)
}
// CopyBuffer is identical to Copy except that it stages through the
// provided buffer (if one is required) rather than allocating a
// temporary one. If buf is nil, one is allocated; otherwise if it has
// zero length, CopyBuffer panics.
//
// If either src implements WriterTo or dst implements ReaderFrom,
// buf will not be used to perform the copy.
func CopyBuffer(dst: Writer, src: Reader, buf: []byte) => (written: i64, err: error) {
if buf != nil && len(buf) == 0 {
panic("empty buffer in CopyBuffer")
}
return copyBuffer(dst, src, buf)
}
// copyBuffer is the actual implementation of Copy and CopyBuffer.
// if buf is nil, one is allocated.
func copyBuffer(dst: Writer, src: Reader, buf: []byte) => (written: i64, err: error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(ReaderFrom); ok {
return rt.ReadFrom(src)
}
if buf == nil {
size := 32 * 1024
if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
if l.N < 1 {
size = 1
} else {
size = int(l.N)
}
}
buf = make([]byte, size)
}
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw < 0 || nr < nw {
nw = 0
if ew == nil {
ew = errInvalidWrite
}
}
written += int64(nw)
if ew != nil {
err = ew
break
}
if nr != nw {
err = ErrShortWrite
break
}
}
if er != nil {
if er != EOF {
err = er
}
break
}
}
return written, err
}
// LimitReader returns a Reader that reads from r
// but stops with EOF after n bytes.
// The underlying implementation is a *LimitedReader.
func LimitReader(r: Reader, n: i64) => Reader { return &LimitedReader{r, n} }
// A LimitedReader reads from R but limits the amount of
// data returned to just N bytes. Each call to Read
// updates N to reflect the new amount remaining.
// Read returns EOF when N <= 0 or when the underlying R returns EOF.
type LimitedReader struct {
R :Reader // underlying reader
N :i64 // max bytes remaining
}
func LimitedReader.Read(p: []byte) => (n: int, err: error) {
if this.N <= 0 {
return 0, EOF
}
if int64(len(p)) > this.N {
p = p[0:this.N]
}
n, err = this.R.Read(p)
this.N -= int64(n)
return
}
// NewSectionReader returns a SectionReader that reads from r
// starting at offset off and stops with EOF after n bytes.
func NewSectionReader(r: ReaderAt, off: i64, n: i64) => *SectionReader {
return &SectionReader{r, off, off, off + n}
}
// SectionReader implements Read, Seek, and ReadAt on a section
// of an underlying ReaderAt.
type SectionReader struct {
r :ReaderAt
base :i64
off :i64
limit :i64
}
func SectionReader.Read(p: []byte) => (n: int, err: error) {
if this.off >= this.limit {
return 0, EOF
}
if max := this.limit - this.off; int64(len(p)) > max {
p = p[0:max]
}
n, err = this.r.ReadAt(p, this.off)
this.off += int64(n)
return
}
var errWhence = errors.New("Seek: invalid whence")
var errOffset = errors.New("Seek: invalid offset")
func SectionReader.Seek(offset: i64, whence: int) => (i64, error) {
switch whence {
default:
return 0, errWhence
case SeekStart:
offset += this.base
case SeekCurrent:
offset += this.off
case SeekEnd:
offset += this.limit
}
if offset < this.base {
return 0, errOffset
}
this.off = offset
return offset - this.base, nil
}
func SectionReader.ReadAt(p: []byte, off: i64) => (n: int, err: error) {
if off < 0 || off >= this.limit-this.base {
return 0, EOF
}
off += this.base
if max := this.limit - off; int64(len(p)) > max {
p = p[0:max]
n, err = this.r.ReadAt(p, off)
if err == nil {
err = EOF
}
return n, err
}
return this.r.ReadAt(p, off)
}
// Size returns the size of the section in bytes.
func SectionReader.Size() => i64 { return this.limit - this.base }
// TeeReader returns a Reader that writes to w what it reads from r.
// All reads from r performed through it are matched with
// corresponding writes to w. There is no internal buffering -
// the write must complete before the read completes.
// Any error encountered while writing is reported as a read error.
func TeeReader(r: Reader, w: Writer) => Reader {
return &teeReader{r, w}
}
type teeReader struct {
r :Reader
w :Writer
}
func teeReader.Read(p: []byte) => (n: int, err: error) {
n, err = this.r.Read(p)
if n > 0 {
if n, err := this.w.Write(p[:n]); err != nil {
return n, err
}
}
return
}
// Discard is a Writer on which all Write calls succeed
// without doing anything.
var Discard :Writer = &discard{}
type discard struct{}
// discard implements ReaderFrom as an optimization so Copy to
// io.Discard can avoid doing unnecessary work.
var _ :ReaderFrom = &discard{}
func discard.Write(p: []byte) => (int, error) {
return len(p), nil
}
func discard.WriteString(s: string) => (int, error) {
return len(s), nil
}
func discard.ReadFrom(r: Reader) => (n: i64, err: error) {
panic("TODO")
}
// NopCloser returns a ReadCloser with a no-op Close method wrapping
// the provided Reader r.
func NopCloser(r: Reader) => ReadCloser {
return &nopCloser{r}
}
type nopCloser struct {
Reader
}
func nopCloser.Close() error { return nil }
// ReadAll reads from r until an error or EOF and returns the data it read.
// A successful call returns err == nil, not err == EOF. Because ReadAll is
// defined to read from src until EOF, it does not treat an EOF from Read
// as an error to be reported.
func ReadAll(r: Reader) => ([]byte, error) {
b := make([]byte, 0, 512)
for {
if len(b) == cap(b) {
// Add more capacity (let append pick how much).
b = append(b, 0)[:len(b)]
}
n, err := r.Read(b[len(b):cap(b)])
b = b[:len(b)+n]
if err != nil {
if err == EOF {
err = nil
}
return b, err
}
}
}
// 版权 @2023 凹语言 作者。保留所有权利。
// ParseBool returns the boolean value represented by the string.
// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
// Any other value returns an error.
func ParseBool(str: string) => (bool, error) {
switch str {
case "1", "t", "T", "true", "TRUE", "True":
return true, nil
case "0", "f", "F", "false", "FALSE", "False":
return false, nil
}
return false, syntaxError("ParseBool", str)
}
// FormatBool returns "true" or "false" according to the value of b.
func FormatBool(b: bool) => string {
if b {
return "true"
}
return "false"
}
// AppendBool appends "true" or "false", according to the value of b,
// to dst and returns the extended buffer.
func AppendBool(dst: []byte, b: bool) => []byte {
if b {
return append(dst, "true"...)
}
return append(dst, "false"...)
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
// 版权 @2023 凹语言 作者。保留所有权利。
// IsDigit reports whether the rune is a decimal digit.
func IsDigit(r: rune) => bool {
if r <= MaxLatin1 {
return '0' <= r && r <= '9'
}
return isExcludingLatin(Digit, r)
}
// 版权 @2023 凹语言 作者。保留所有权利。
// Bit masks for each code point under U+0100, for fast lookup.
const (
pC = 1 << iota // a control character.
pP // a punctuation character.
pN // a numeral.
pS // a symbolic character.
pZ // a spacing character.
pLu // an upper-case letter.
pLl // a lower-case letter.
pp // a printable character according to Go's definition.
pg = pp | pZ // a graphical character according to the Unicode definition.
pLo = pLl | pLu // a letter that is neither upper nor lower case.
pLmask = pLo
)
// GraphicRanges defines the set of graphic characters according to Unicode.
var GraphicRanges = []*RangeTable{
L, M, N, P, S, Zs,
}
// PrintRanges defines the set of printable characters according to Go.
// ASCII space, U+0020, is handled separately.
var PrintRanges = []*RangeTable{
L, M, N, P, S,
}
// IsGraphic reports whether the rune is defined as a Graphic by Unicode.
// Such characters include letters, marks, numbers, punctuation, symbols, and
// spaces, from categories L, M, N, P, S, Zs.
func IsGraphic(r: rune) => bool {
// We convert to uint32 to avoid the extra test for negative,
// and in the index we convert to uint8 to avoid the range check.
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&pg != 0
}
return In(r, GraphicRanges...)
}
// IsPrint reports whether the rune is defined as printable by Go. Such
// characters include letters, marks, numbers, punctuation, symbols, and the
// ASCII space character, from categories L, M, N, P, S and the ASCII space
// character. This categorization is the same as IsGraphic except that the
// only spacing character is ASCII space, U+0020.
func IsPrint(r: rune) => bool {
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&pp != 0
}
return In(r, PrintRanges...)
}
// IsOneOf reports whether the rune is a member of one of the ranges.
// The function "In" provides a nicer signature and should be used in preference to IsOneOf.
func IsOneOf(ranges: []*RangeTable, r: rune) => bool {
for _, inside := range ranges {
if Is(inside, r) {
return true
}
}
return false
}
// In reports whether the rune is a member of one of the ranges.
func In(r: rune, ranges: ...*RangeTable) => bool {
for _, inside := range ranges {
if Is(inside, r) {
return true
}
}
return false
}
// IsControl reports whether the rune is a control character.
// The C (Other) Unicode category includes more code points
// such as surrogates; use Is(C, r) to test for them.
func IsControl(r: rune) => bool {
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&pC != 0
}
// All control characters are < MaxLatin1.
return false
}
// IsLetter reports whether the rune is a letter (category L).
func IsLetter(r: rune) => bool {
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&(pLmask) != 0
}
return isExcludingLatin(Letter, r)
}
// IsMark reports whether the rune is a mark character (category M).
func IsMark(r: rune) => bool {
// There are no mark characters in Latin-1.
return isExcludingLatin(Mark, r)
}
// IsNumber reports whether the rune is a number (category N).
func IsNumber(r: rune) => bool {
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&pN != 0
}
return isExcludingLatin(Number, r)
}
// IsPunct reports whether the rune is a Unicode punctuation character
// (category P).
func IsPunct(r: rune) => bool {
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&pP != 0
}
return Is(Punct, r)
}
// IsSpace reports whether the rune is a space character as defined
// by Unicode's White Space property; in the Latin-1 space
// this is
// '\t', '\n', '\v', '\f', '\r', ' ', U+0085 (NEL), U+00A0 (NBSP).
// Other definitions of spacing characters are set by category
// Z and property Pattern_White_Space.
func IsSpace(r: rune) => bool {
// This property isn't the same as Z; special-case it.
if uint32(r) <= MaxLatin1 {
switch r {
case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
return true
}
return false
}
return isExcludingLatin(White_Space, r)
}
// IsSymbol reports whether the rune is a symbolic character.
func IsSymbol(r: rune) => bool {
if uint32(r) <= MaxLatin1 {
return properties[uint8(r)]&pS != 0
}
return isExcludingLatin(Symbol, r)
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册