diff --git a/data/tablets/XPPEN-tablets.json b/data/tablets/XPPEN-tablets.json index a5db850..09a46ea 100644 --- a/data/tablets/XPPEN-tablets.json +++ b/data/tablets/XPPEN-tablets.json @@ -5,7 +5,7 @@ "EntityId": "xppen.tablet.9494g", "_id": "b4c5d6e7-f8a9-4b0c-d1e2-f3a4b5c6d7e8", "_CreateDate": "2026-04-13T00:00:00.000Z", - "_ModifiedDate": "2026-10-02T20:21:11.000Z" + "_ModifiedDate": "2026-10-02T21:41:21.053Z" }, "Model": { "Brand": "XPPEN", @@ -145,7 +145,9 @@ }, "Density": "100", "AccuracyCenter": "0.5", - "AccuracyCorner": "1.5" + "AccuracyCorner": "1.5", + "MaxHover": "20", + "MaxHoverMin": "10" }, "Display": { "PixelDimensions": { @@ -5777,7 +5779,7 @@ "EntityId": "xppen.tablet.mdp1221", "_id": "e4f7a8b2-c3d1-4e5f-9a0b-1c2d3e4f5a6b", "_CreateDate": "2026-04-13T00:00:00.000Z", - "_ModifiedDate": "2026-10-02T20:27:03.000Z" + "_ModifiedDate": "2026-10-02T21:41:23.467Z" }, "Model": { "Brand": "XPPEN", @@ -5893,7 +5895,9 @@ "Density": "100", "Tilt": "60", "AccuracyCenter": "0.4", - "AccuracyCorner": "1.5" + "AccuracyCorner": "1.5", + "MaxHover": "20", + "MaxHoverMin": "10" }, "Display": { "PixelDimensions": { diff --git a/data/version.json b/data/version.json index cdddcf6..e889c10 100644 --- a/data/version.json +++ b/data/version.json @@ -119,7 +119,7 @@ "xppen.pen.pd04b": 2 } }, - "sourceDigest": "956f1bde67ac7ce09beaad4c5416a7fb5c38eb0c78ea941f0354ca51b92304ee", + "sourceDigest": "f12496a3b1b93aa9139dfd530ffd39a28d85961aa19a577770322ff3f3293dcb", "bundles": [ { "path": "tablets/APPLE-tablets.json", @@ -173,7 +173,7 @@ }, { "path": "tablets/XPPEN-tablets.json", - "sha256": "d14f9369aaa11a3b1e6d2d4bfccf2097857837d1c00af1a947172dc61d31d32d", + "sha256": "ac475528545dd74ec919110486375545a77b02e2296a540a351f9fa05bf4ea5e", "count": 69 }, { diff --git a/docs/DECISIONS.txt b/docs/DECISIONS.txt index 994e21c..c47e085 100644 --- a/docs/DECISIONS.txt +++ b/docs/DECISIONS.txt @@ -8,6 +8,8 @@ This document records key design decisions for the DrawTabData project. Decided by the author while reviewing the source checks: - Physical depth ranges ("19~26.7 mm") are stored as Depth (max) and DepthMin (min); a single depth is the max. +- Hover ranges ("Reading Height 10~20 mm") work the same way: MaxHover + (max) and MaxHoverMin (min); a single hover value is the max. - A single accuracy figure with no center/corner split goes in AccuracyCenter. - A built-in fold-out stand counts as Legs only, not IncludedStand. diff --git a/docs/FIELDS.txt b/docs/FIELDS.txt index c7a6bac..33c8081 100644 --- a/docs/FIELDS.txt +++ b/docs/FIELDS.txt @@ -173,6 +173,14 @@ Format: integer string (e.g. "10", "12") Unit: mm Required: no +### Digitizer.MaxHoverMin +The low end when the manufacturer gives hover height as a range ("Reading +Height 10~20 mm"): MaxHover holds the maximum and MaxHoverMin the minimum. A +single hover value is treated as the maximum (MaxHover). +Format: integer string (e.g. "10") +Unit: mm +Required: no + ## Display group diff --git a/lib/entities/spec-conventions.test.ts b/lib/entities/spec-conventions.test.ts index dca89bc..c746cd5 100644 --- a/lib/entities/spec-conventions.test.ts +++ b/lib/entities/spec-conventions.test.ts @@ -24,6 +24,13 @@ describe("spec conventions (#54)", () => { expect(v.safeParse(TabletSchema, { ...base, Digitizer: { Dimensions: { Width: 1, Height: 1, DepthMin: 1 } } }).success).toBe(false); }); + it("stores a hover range as MaxHoverMin and MaxHover (max)", () => { + const t = { ...base, Digitizer: { MaxHover: "20", MaxHoverMin: "10" } }; + expect(v.safeParse(TabletSchema, t).success).toBe(true); + expect(field("DigitizerMaxHover").getValue(t as unknown as Tablet)).toBe("20"); + expect(field("DigitizerMaxHoverMin").getValue(t as unknown as Tablet)).toBe("10"); + }); + it("keeps a separate Bluetooth report rate", () => { const t = { ...base, Digitizer: { ReportRate: "300", ReportRateBluetooth: "133" } }; expect(v.safeParse(TabletSchema, t).success).toBe(true); diff --git a/lib/entities/tablet-fields.ts b/lib/entities/tablet-fields.ts index 15156c9..094674c 100644 --- a/lib/entities/tablet-fields.ts +++ b/lib/entities/tablet-fields.ts @@ -202,6 +202,7 @@ export const TABLET_FIELDS: FieldDisplayDef[] = [ { key: "DigitizerAccuracyCenter", label: "Accuracy Center (mm)", getValue: (t) => t.Digitizer?.AccuracyCenter ?? "", type: "number", group: "Digitizer", unit: "mm" }, { key: "DigitizerAccuracyCorner", label: "Accuracy Corner (mm)", getValue: (t) => t.Digitizer?.AccuracyCorner ?? "", type: "number", group: "Digitizer", unit: "mm" }, { key: "DigitizerMaxHover", label: "Max Hover (mm)", getValue: (t) => t.Digitizer?.MaxHover ?? "", type: "number", group: "Digitizer", unit: "mm" }, + { key: "DigitizerMaxHoverMin", label: "Max Hover, Low End (mm)", getValue: (t) => t.Digitizer?.MaxHoverMin ?? "", type: "number", group: "Digitizer", unit: "mm" }, { key: "DigitizerDimensions", label: "Dimensions (mm)", group: "Digitizer", unit: "mm", getValue: (t) => { const d = t.Digitizer?.Dimensions; return d ? `${d.Width} x ${d.Height}` : ""; }, diff --git a/lib/schemas.ts b/lib/schemas.ts index 8545520..0c83195 100644 --- a/lib/schemas.ts +++ b/lib/schemas.ts @@ -193,7 +193,10 @@ const DigitizerSchema = v.strictObject({ Tilt: v.optional(NumericString), AccuracyCenter: v.optional(NumericString), AccuracyCorner: v.optional(NumericString), + // A spec that gives hover as a range ("10~20 mm") stores the maximum in + // MaxHover and the minimum in MaxHoverMin; a single value is the maximum. MaxHover: v.optional(NumericString), + MaxHoverMin: v.optional(NumericString), }); const DisplaySchema = v.strictObject({ diff --git a/source/tablets/xppen/xppen.tablet.9494g.json b/source/tablets/xppen/xppen.tablet.9494g.json index 6c1ccd7..c487abc 100644 --- a/source/tablets/xppen/xppen.tablet.9494g.json +++ b/source/tablets/xppen/xppen.tablet.9494g.json @@ -3,7 +3,7 @@ "EntityId": "xppen.tablet.9494g", "_id": "b4c5d6e7-f8a9-4b0c-d1e2-f3a4b5c6d7e8", "_CreateDate": "2026-04-13T00:00:00.000Z", - "_ModifiedDate": "2026-10-02T20:21:11.000Z" + "_ModifiedDate": "2026-10-02T21:41:21.053Z" }, "Model": { "Brand": "XPPEN", @@ -143,7 +143,9 @@ }, "Density": "100", "AccuracyCenter": "0.5", - "AccuracyCorner": "1.5" + "AccuracyCorner": "1.5", + "MaxHover": "20", + "MaxHoverMin": "10" }, "Display": { "PixelDimensions": { diff --git a/source/tablets/xppen/xppen.tablet.mdp1221.json b/source/tablets/xppen/xppen.tablet.mdp1221.json index 938880f..abc802f 100644 --- a/source/tablets/xppen/xppen.tablet.mdp1221.json +++ b/source/tablets/xppen/xppen.tablet.mdp1221.json @@ -3,7 +3,7 @@ "EntityId": "xppen.tablet.mdp1221", "_id": "e4f7a8b2-c3d1-4e5f-9a0b-1c2d3e4f5a6b", "_CreateDate": "2026-04-13T00:00:00.000Z", - "_ModifiedDate": "2026-10-02T20:27:03.000Z" + "_ModifiedDate": "2026-10-02T21:41:23.467Z" }, "Model": { "Brand": "XPPEN", @@ -119,7 +119,9 @@ "Density": "100", "Tilt": "60", "AccuracyCenter": "0.4", - "AccuracyCorner": "1.5" + "AccuracyCorner": "1.5", + "MaxHover": "20", + "MaxHoverMin": "10" }, "Display": { "PixelDimensions": {