@@ -70,24 +70,6 @@ final class DataGridCellFactory {
7070 }
7171 }
7272
73- // MARK: - Cached Fonts (avoid recreation per cell render)
74-
75- private enum CellFonts {
76- static let regular = NSFont . monospacedSystemFont (
77- ofSize: DesignConstants . FontSize. body,
78- weight: . regular
79- )
80- static let italic = regular. withTraits ( . italic)
81- static let medium = NSFont . monospacedSystemFont (
82- ofSize: DesignConstants . FontSize. body,
83- weight: . medium
84- )
85- static let rowNumber = NSFont . monospacedDigitSystemFont (
86- ofSize: DesignConstants . FontSize. medium,
87- weight: . regular
88- )
89- }
90-
9173 // MARK: - Cached Colors (avoid allocation per cell render)
9274
9375 private enum CellColors {
@@ -114,13 +96,15 @@ final class DataGridCellFactory {
11496 let textField = reused. textField {
11597 cellView = reused
11698 cell = textField
99+ cell. font = DataGridFontCache . rowNumber
117100 } else {
118101 cellView = NSTableCellView ( )
119102 cellView. identifier = cellViewId
120103
121104 cell = NSTextField ( labelWithString: " " )
122105 cell. alignment = . right
123- cell. font = CellFonts . rowNumber
106+ cell. font = DataGridFontCache . rowNumber
107+ cell. tag = DataGridFontVariant . rowNumber
124108 cell. textColor = . secondaryLabelColor
125109 cell. translatesAutoresizingMaskIntoConstraints = false
126110
@@ -194,7 +178,7 @@ final class DataGridCellFactory {
194178 cellView. canDrawSubviewsIntoLayer = true
195179
196180 cell = CellTextField ( )
197- cell. font = CellFonts . regular
181+ cell. font = DataGridFontCache . regular
198182 cell. drawsBackground = false
199183 cell. isBordered = false
200184 cell. focusRingType = . none
@@ -330,35 +314,28 @@ final class DataGridCellFactory {
330314
331315 if value == nil {
332316 cell. stringValue = " "
317+ cell. font = DataGridFontCache . italic
318+ cell. tag = DataGridFontVariant . italic
333319 if !isLargeDataset {
334320 cell. placeholderString = nullDisplayString
335- cell. textColor = . secondaryLabelColor
336- if cell. font !== CellFonts . italic {
337- cell. font = CellFonts . italic
338- }
339- } else {
340- cell. textColor = . secondaryLabelColor
341321 }
322+ cell. textColor = . secondaryLabelColor
342323 } else if value == " __DEFAULT__ " {
343324 cell. stringValue = " "
325+ cell. font = DataGridFontCache . medium
326+ cell. tag = DataGridFontVariant . medium
344327 if !isLargeDataset {
345328 cell. placeholderString = " DEFAULT "
346- cell. textColor = . systemBlue
347- cell. font = CellFonts . medium
348- } else {
349- cell. textColor = . systemBlue
350329 }
330+ cell. textColor = . systemBlue
351331 } else if value == " " {
352332 cell. stringValue = " "
333+ cell. font = DataGridFontCache . italic
334+ cell. tag = DataGridFontVariant . italic
353335 if !isLargeDataset {
354336 cell. placeholderString = " Empty "
355- cell. textColor = . secondaryLabelColor
356- if cell. font !== CellFonts . italic {
357- cell. font = CellFonts . italic
358- }
359- } else {
360- cell. textColor = . secondaryLabelColor
361337 }
338+ cell. textColor = . secondaryLabelColor
362339 } else {
363340 var displayValue = value ?? " "
364341
@@ -378,9 +355,8 @@ final class DataGridCellFactory {
378355 cell. stringValue = displayValue
379356 ( cell as? CellTextField ) ? . originalValue = value
380357 cell. textColor = . labelColor
381- if cell. font !== CellFonts . regular {
382- cell. font = CellFonts . regular
383- }
358+ cell. font = DataGridFontCache . regular
359+ cell. tag = DataGridFontVariant . regular
384360 }
385361 }
386362
@@ -394,13 +370,6 @@ final class DataGridCellFactory {
394370 private static let sampleRowCount = 30
395371 /// Maximum characters to consider per cell for width estimation
396372 private static let maxMeasureChars = 50
397- /// Font for measuring cell content (monospaced — all glyphs have equal advance)
398- private static let measureFont = NSFont . monospacedSystemFont ( ofSize: DesignConstants . FontSize. body, weight: . regular)
399- /// Pre-computed advance width of a single monospaced glyph (avoids per-row CoreText calls)
400- private static let monoCharWidth : CGFloat = {
401- let attrs : [ NSAttributedString . Key : Any ] = [ . font: measureFont]
402- return ( " M " as NSString ) . size ( withAttributes: attrs) . width
403- } ( )
404373 /// Font for measuring header
405374 private static let headerFont = NSFont . systemFont ( ofSize: DesignConstants . FontSize. body, weight: . semibold)
406375
@@ -432,14 +401,14 @@ final class DataGridCellFactory {
432401 // instead of CoreText measurement. ~0.6 of mono width is a good estimate
433402 // for proportional system font.
434403 let headerCharCount = ( columnName as NSString ) . length
435- var maxWidth = CGFloat ( headerCharCount) * Self . monoCharWidth * 0.75 + 48
404+ var maxWidth = CGFloat ( headerCharCount) * DataGridFontCache . monoCharWidth * 0.75 + 48
436405
437406 let totalRows = rowProvider. totalRowCount
438407 let columnCount = rowProvider. columns. count
439408 // Reduce sample count for wide tables to keep total work bounded
440409 let effectiveSampleCount = columnCount > 50 ? 10 : Self . sampleRowCount
441410 let step = max ( 1 , totalRows / effectiveSampleCount)
442- let charWidth = Self . monoCharWidth
411+ let charWidth = DataGridFontCache . monoCharWidth
443412
444413 for i in stride ( from: 0 , to: totalRows, by: step) {
445414 guard let value = rowProvider. value ( atRow: i, column: columnIndex) else { continue }
0 commit comments