-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.go
More file actions
172 lines (153 loc) · 4.83 KB
/
Copy pathtypes.go
File metadata and controls
172 lines (153 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Package ncode defines the Ncode domain types used across the SDK.
//
// Types here mirror the public surface of NeoLAB's NcodeSDK 2.0
// (see https://github.com/NeoSmartpen/Ncode-SDK2.0) but are redefined
// in native Go so the SDK has no compile-time dependency on the
// proprietary Windows-only NeoLABNcodeSDK binary. The runtime
// dependency lives in pattern/neolab and is reached through a
// subprocess.
package ncode
import (
"errors"
"fmt"
"strings"
)
// NcodeType identifies which Ncode encoding a ticket or page uses.
type NcodeType uint8
const (
NcodeTypeNone NcodeType = iota
NcodeTypeN3C6
NcodeTypeG3C6
NcodeTypeS1C6
NcodeTypeP1C6
)
// SupportsLineMode reports whether the type can be rendered as a line
// pattern in addition to dots. Only N3C6 and G3C6 support line mode;
// the others are dot-only per the NcodeSDK 2.0 documentation.
func (t NcodeType) SupportsLineMode() bool {
return t == NcodeTypeN3C6 || t == NcodeTypeG3C6
}
// SupportsPostscript reports whether GetPostscript-style output is
// permitted for this type (S1C6 / P1C6 only).
func (t NcodeType) SupportsPostscript() bool {
return t == NcodeTypeS1C6 || t == NcodeTypeP1C6
}
func (t NcodeType) String() string {
switch t {
case NcodeTypeNone:
return "NONE"
case NcodeTypeN3C6:
return "N3C6"
case NcodeTypeG3C6:
return "G3C6"
case NcodeTypeS1C6:
return "S1C6"
case NcodeTypeP1C6:
return "P1C6"
default:
return fmt.Sprintf("NcodeType(%d)", t)
}
}
// ParseNcodeType resolves a textual type name (case-insensitive) to an enum.
func ParseNcodeType(s string) (NcodeType, error) {
switch strings.ToUpper(s) {
case "NONE", "":
return NcodeTypeNone, nil
case "N3C6":
return NcodeTypeN3C6, nil
case "G3C6":
return NcodeTypeG3C6, nil
case "S1C6":
return NcodeTypeS1C6, nil
case "P1C6":
return NcodeTypeP1C6, nil
default:
return NcodeTypeNone, fmt.Errorf("unknown NcodeType %q", s)
}
}
// Ticket is an allocation of Ncode identifier space granted by NeoLAB.
// Construct it directly from a NeoLAB-issued range; this SDK does not
// dictate how applications persist tickets.
type Ticket struct {
ID string // application-defined identifier
Type NcodeType // Ncode encoding this ticket allocates
Section int
OwnerStart int
OwnerSize int
BookStart int
BookSize int
PageStart int
PageSize int
Period int // unit unspecified by the SDK; stored as-is
ExtraInfo string // free-form metadata
}
// Contains reports whether (owner, book, page) falls within the ticket's
// allocated ranges.
func (t Ticket) Contains(owner, book, page int) bool {
return owner >= t.OwnerStart && owner < t.OwnerStart+t.OwnerSize &&
book >= t.BookStart && book < t.BookStart+t.BookSize &&
page >= t.PageStart && page < t.PageStart+t.PageSize
}
// ErrOffsetOutOfRange is returned when Resolve receives offsets that fall
// outside the ticket's allocation.
var ErrOffsetOutOfRange = errors.New("ticket offset out of range")
// Resolve mirrors SetStartPageFromTicket from NcodeSDK 2.0: apply offsets
// to the ticket's start points and return the resulting page identifier.
// Out of range offsets yield ErrOffsetOutOfRange.
func (t Ticket) Resolve(ownerOffset, bookOffset, pageOffset int) (PageID, error) {
if ownerOffset < 0 || ownerOffset >= t.OwnerSize ||
bookOffset < 0 || bookOffset >= t.BookSize ||
pageOffset < 0 || pageOffset >= t.PageSize {
return PageID{}, ErrOffsetOutOfRange
}
return PageID{
Section: t.Section,
Owner: t.OwnerStart + ownerOffset,
Book: t.BookStart + bookOffset,
Page: t.PageStart + pageOffset,
}, nil
}
// PageID is the 4-tuple that uniquely addresses a page within the Ncode
// identifier space.
type PageID struct {
Section int
Owner int
Book int
Page int
}
func (p PageID) String() string {
return fmt.Sprintf("%d.%d.%d.%d", p.Section, p.Owner, p.Book, p.Page)
}
// Page describes a single Ncode page that will be generated or overlaid.
// Width and Height are in inches, never pixels — matching the SDK
// convention.
type Page struct {
Type NcodeType
ID PageID
WidthInch float64
HeightInch float64
}
// PaperSize is a page size expressed in inches. Matches the SDK's SizeF
// return from GetInchValueFromPaperName.
type PaperSize struct {
WidthInch float64
HeightInch float64
}
// A4 is the ISO 216 A4 paper size in inches, rounded to two decimals as
// the NeoLAB SDK accepts. 0.01 in at 600 DPI is 6 pixels, well below the
// finest dot pitch.
var A4 = PaperSize{WidthInch: 8.27, HeightInch: 11.69}
// DotMode selects between dot and line rendering. Line is only honored
// when NcodeType.SupportsLineMode() is true; otherwise generators must
// fall back to dot.
type DotMode uint8
const (
DotModeDot DotMode = 0 // default; all types support it
DotModeLine DotMode = 1 // N3C6 / G3C6 only
)
func (m DotMode) String() string {
if m == DotModeLine {
return "line"
}
return "dot"
}