altium-toolkit 1.1.39 → 1.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "altium-toolkit",
3
- "version": "1.1.39",
3
+ "version": "1.1.40",
4
4
  "description": "Altium document parsing and non-interactive rendering utilities",
5
5
  "keywords": [
6
6
  "altium",
@@ -873,11 +873,18 @@ export class SchematicPinParser {
873
873
  ownerDrawnInternalPinOwners.has(ownerIndex) &&
874
874
  SchematicPinParser.#isCompactNumberedFetTerminalGroup(
875
875
  normalizedPins,
876
- semanticNames,
877
876
  orientationCount
878
877
  )
879
878
  ) {
880
879
  labelMode = 'number-only'
880
+ } else if (
881
+ ownerDrawnInternalPinOwners.has(ownerIndex) &&
882
+ SchematicPinParser.#isOwnerDrawnAmplifierTerminalGroup(
883
+ normalizedPins,
884
+ semanticNames
885
+ )
886
+ ) {
887
+ labelMode = 'number-only'
881
888
  } else if (
882
889
  SchematicPinParser.#isOwnerDrawnTerminalGlyphGroup(
883
890
  normalizedPins,
@@ -957,32 +964,94 @@ export class SchematicPinParser {
957
964
  }
958
965
 
959
966
  /**
960
- * Returns true when a compact owner-drawn FET body uses semantic terminal
961
- * names internally but still exposes external numeric contact labels.
967
+ * Returns true when a compact owner-drawn FET body or pin array uses
968
+ * semantic terminal names internally but still exposes external numeric
969
+ * contact labels.
962
970
  * @param {{ designator: string, name: string, orientation: 'left' | 'right' | 'top' | 'bottom' }[]} pins
963
- * @param {string[]} semanticNames
964
971
  * @param {number} orientationCount
965
972
  * @returns {boolean}
966
973
  */
967
- static #isCompactNumberedFetTerminalGroup(
968
- pins,
969
- semanticNames,
970
- orientationCount
971
- ) {
974
+ static #isCompactNumberedFetTerminalGroup(pins, orientationCount) {
972
975
  if (
973
- pins.length !== 4 ||
974
- orientationCount < 3 ||
976
+ pins.length < 4 ||
977
+ pins.length > 12 ||
978
+ orientationCount < 2 ||
979
+ !pins.every((pin) => /^\d+$/.test(String(pin.designator || '')))
980
+ ) {
981
+ return false
982
+ }
983
+
984
+ const normalizedNames = pins.map((pin) =>
985
+ String(pin.name || '')
986
+ .trim()
987
+ .toUpperCase()
988
+ )
989
+
990
+ return (
991
+ new Set(normalizedNames).size >= 2 &&
992
+ normalizedNames.every((name) =>
993
+ SchematicPinParser.#isFetTerminalName(name)
994
+ )
995
+ )
996
+ }
997
+
998
+ /**
999
+ * Returns true when an owner-drawn amplifier body already represents its
1000
+ * input, output, and supply terminal names in the drawn symbol artwork.
1001
+ * @param {{ designator: string, name: string }[]} pins
1002
+ * @param {string[]} semanticNames
1003
+ * @returns {boolean}
1004
+ */
1005
+ static #isOwnerDrawnAmplifierTerminalGroup(pins, semanticNames) {
1006
+ if (
1007
+ pins.length < 3 ||
1008
+ pins.length > 8 ||
975
1009
  semanticNames.length !== pins.length ||
976
1010
  !pins.every((pin) => /^\d+$/.test(String(pin.designator || '')))
977
1011
  ) {
978
1012
  return false
979
1013
  }
980
1014
 
981
- return semanticNames.every((name) =>
982
- SchematicPinParser.#isFetTerminalName(name)
1015
+ const normalizedNames = semanticNames.map((name) =>
1016
+ SchematicPinParser.#normalizeAmplifierTerminalName(name)
1017
+ )
1018
+
1019
+ return (
1020
+ normalizedNames.every(Boolean) &&
1021
+ normalizedNames.some((name) => name === 'IN+' || name === 'IN-') &&
1022
+ normalizedNames.includes('OUT')
983
1023
  )
984
1024
  }
985
1025
 
1026
+ /**
1027
+ * Normalizes amplifier terminal names that are normally drawn inside the
1028
+ * owner-authored symbol body.
1029
+ * @param {string} name Raw pin name.
1030
+ * @returns {string}
1031
+ */
1032
+ static #normalizeAmplifierTerminalName(name) {
1033
+ const normalized = String(name || '')
1034
+ .trim()
1035
+ .toUpperCase()
1036
+
1037
+ switch (normalized) {
1038
+ case 'IN+':
1039
+ case '+IN':
1040
+ case '+':
1041
+ return 'IN+'
1042
+ case 'IN-':
1043
+ case '-IN':
1044
+ case '-':
1045
+ return 'IN-'
1046
+ case 'OUT':
1047
+ case 'V+':
1048
+ case 'V-':
1049
+ return normalized
1050
+ default:
1051
+ return ''
1052
+ }
1053
+ }
1054
+
986
1055
  /**
987
1056
  * Returns true when a compact multi-side owner has transistor-like terminal
988
1057
  * letters that are part of the drawn symbol body, not external pin labels.
@@ -49,6 +49,12 @@ export class SchematicColorResolver {
49
49
  return normalized
50
50
  }
51
51
 
52
+ if (SchematicColorResolver.#isDefaultInkSourceColor(normalized)) {
53
+ return SchematicColorResolver.#toVariable(
54
+ '--schematic-default-ink-color'
55
+ )
56
+ }
57
+
52
58
  const token = COLOR_TOKEN_BY_VALUE.get(normalized)
53
59
 
54
60
  if (token) {
@@ -316,6 +322,30 @@ export class SchematicColorResolver {
316
322
  return Math.max(rgb.r, rgb.g, rgb.b) <= 32
317
323
  }
318
324
 
325
+ /**
326
+ * Returns true for dark saturated blue source colors that represent
327
+ * Altium's default schematic ink family rather than custom artwork color.
328
+ * @param {string} color Normalized color.
329
+ * @returns {boolean}
330
+ */
331
+ static #isDefaultInkSourceColor(color) {
332
+ const rgb = SchematicColorResolver.#parseHexColor(color)
333
+ if (!rgb) {
334
+ return false
335
+ }
336
+
337
+ const hsl = SchematicColorResolver.#rgbToHsl(rgb)
338
+ const hueDegrees = hsl.h * 360
339
+
340
+ return (
341
+ hueDegrees >= 220 &&
342
+ hueDegrees <= 270 &&
343
+ hsl.s >= 45 &&
344
+ hsl.l >= 12 &&
345
+ hsl.l <= 38
346
+ )
347
+ }
348
+
319
349
  /**
320
350
  * Converts RGB channels to HSL.
321
351
  * @param {{ r: number, g: number, b: number }} color