Sign in Join
Wiki copytemporary

Cocoa Internals/Graphics: what changed

Revision 3 to 4. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Colors
22
33Cocoa-WS should be using device-dependent colors to match colors across other widgetsets.
44
55That applies to color of Pen, Brush and Font.
66
77
88The “Device” color-space names represent color spaces in which component values are applied to devices as specified. There is no optimization or adjustment for differences between devices in how they render colors. If you know exactly which device is connected to a system and you want to print or display a certain color on that device, then it makes sense to use a appropriate device-dependent color space when creating NSColor objects. However, it is usually not the case that an application knows which devices are connected and their specific color spaces. If you specify components of a color in a device-dependent color space—let’s say NSDeviceRGBColorSpace—and then have several displays render this color, you will see several slightly different colors.
99
1010
1111To get around this problem you can use calibrated color spaces, which are designated by two of the color-space names in Table 1. A calibrated color space is a device-independent color space. The color spaces designated by NSCalibratedWhiteColorSpace and NSCalibratedRGBColorSpace color spaces are calibrated to a device that best represents devices in a particular class, such as color displays. It allows your application to present reasonably accurate colors when you are unsure about the color space of a device in a particular context.
1212
1313### System Colors
1414
1515NSColor class provides a large variety of system themed colors:
1616
1717**Constant**
1818
1919**LCL definition**
2020
2121**NSColor**
2222
2323**[Cocoa definition](https://developer.apple.com/documentation/appkit/nscolor?language=objc)**
2424
2525clScrollBar
2626
2727Scrollbar body
2828
2929scrollBarColor
3030
3131Returns the system color used for scroll “bars”—that is, for the groove in which a scroller’s knob moves
3232
3333clBackground
3434
3535Desktop background color
3636
3737windowBackgroundColor
3838
3939Returns a pattern color that will draw the ruled lines for the window background.
4040
4141clActiveCaption
4242
4343Active window titlebar
4444
4545windowFrameColor
4646
4747Returns the system color used for window frames, except for their text.
4848
4949clInactiveCaption
5050
5151Inactive window titlebar
5252
5353windowBackgroundColor
5454
5555clMenu
5656
5757Regular menu item background color
5858
5959controlBackgroundColor
6060
6161Returns the system color used for the background of large controls.
6262
6363clWindow
6464
6565The normal background brush of unselected text. Defined for controls like TEdit, TComboBox, TMemo, TListBox, TTreeView.
6666
6767textBackgroundColor
6868
6969Returns the system color used for the text background.
7070
7171clWindowFrame
7272
7373Color of frame around the window
7474
7575windowFrameColor
7676
7777clMenuText
7878
7979The font color to use together with clMenu
8080
8181controlTextColor
8282
8383Returns the system color used for text on controls that aren’t disabled.
8484
8585clWindowText
8686
8787Font color to use together with clWindow
8888
8989controlTextColor
9090
9191clCaptionText
9292
9393Active window titlebar text color
9494
9595windowFrameTextColor
9696
9797Returns the system color used for the text in window frames.
9898
9999clActiveBorder
100100
101101?
102102
103103windowFrameColor
104104
105105clInactiveBorder
106106
107107?
108108
109109windowFrameColor
110110
111111clAppWorkspace
112112
113113MDIMain form background
114114
115115windowBackgroundColor
116116
117117clHighlight
118118
119119The brush color of selected element
120120
121121selectedControlColor
122122
123123Returns the system color used for the face of a selected control—a control that has been clicked or is being dragged.
124124
125125clHighlightText
126126
127127Font color of selected text (to use together with clHighligh).
128128
129129selectedControlTextColor
130130
131131Returns the system color used for text in a selected control—a control being clicked or dragged.
132132
133133clBtnFace
134134
135135Button background
136136
137137controlColor
138138
139139Returns the system color used for the flat surfaces of a control.
140140
141141clBtnShadow
142142
143143Button shadow color (bottom right) used to achieve 3D effect
144144
145145controlShadowColor
146146
147147Returns the system color used for the shadows dropped from controls.
148148
149149clGrayText
150150
151151The font color of disabled element
152152
153153disabledControlTextColor
154154
155155Returns the system color used for text on disabled controls.
156156
157157clBtnText
158158
159159Button font color to use together with clBtnFace
160160
161161controlTextColor
162162
163163clInactiveCaptionText
164164
165165Inactive window titlebar text color
166166
167167windowFrameTextColor
168168
169169clBtnHighlight
170170
171171Button highlight color (top left) used to achieve 3D effect
172172
173173controlLightHighlightColor
174174
175175Returns the system color used for light highlights in controls.
176176
177177cl3DDkShadow
178178
179179?
180180
181181controlDarkShadowColor
182182
183183Returns the system color used for the dark edge of the shadow dropped from controls.
184184
185185cl3DLight
186186
187187?
188188
189189controlHighlightColor
190190
191191Returns the system color used for the highlighted bezels of controls.
192192
193193clInfoText
194194
195195Font color for hints. Use together with clInfoBk
196196
197197controlTextColor
198198
199199clInfoBk
200200
201201Brush color for hints. Use together with clInfoText
202202
203203*hard coded*
204204
205205The actual color value depends on MacOS version. Before macOS 10.10 (Yosemite) the color is yellowish. on 10.10 and after, the color is gray. The change follows Apple system hint color change. The API to identify hint window color is unknown.
206206
207207CocoaInt unit also provides a global variable CocoaHintColor. The value is used to return value for clInfoBk. Thus if Apple changes the design in future, you can always adjust hint color from your code.
208208
209209clHotLight
210210
211211?
212212
213213alternateSelectedControlColor
214214
215215Returns the system color used for the face of a selected control in a list or table.
216216
217217clGradientActiveCaption
218218
219219The second color used to make gradient of active window titlebar
220220
221221windowFrameColor
222222
223223clGradientInactiveCaption
224224
225225The second color used to make gradient for inactive window titlebar
226226
227227windowBackgroundColor
228228
229229clMenuHighlight
230230
231231The background color of selected menu item
232232
233233selectedMenuItemColor
234234
235235Returns the system color used for the face of selected menu items. (depreciated in macOS 10.14)
236236
237237clMenuBar
238238
239239The Backround color of menu bar
240240
241241selectedTextBackgroundColor
242242
243243Returns the system color used for the background of selected text.
244244
245245clForm
246246
247247?
248248
249249windowBackgroundColor
250250
251251clColorDesktop
252252
253253?
254254
255255cl3DFace
256256
257257?
258258
259259cl3DShadow
260260
261261?
262262
263263cl3DHiLight
264264
265265?
266266
267267clBtnHiLight
268268
269269Same as clBtnHighlight
270270
271271For Reference: [Apple Human Interface Guidelines - Dynamic System Colors](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color/#dynamic-system-colors)
272272
273273### Hint Window
274274
275275Cocoa provides its own API to show a popup hint window. Thus Cocoa doesn't provide must information on how hint popup window should actually be shown.
276276
277277On dark theme of Mojave system, it became a bit more complicated. Besides a different fill color for darktheme, the popup window also draws a border of light pixels. ![](/wiki-images/2/2f/Mojave-DarkLight-Tooltip.png)
278278
279279## Fonts
280280
281281Historically, MacOS (Classic MacOS, Mac OS X, and macOS) systems are using **72** ppi (or dpi). Windows is using **96** dpi (so do Linux desktop managers).
282282
283283### Default
284284
285285NSFont class provides a number of class methods to get proper system font without selecting the font by name. The same of getting system-native font size.
286286
287287### 96 DPI
288288
289289macOS native DPI (aka PPI) is 72 (it matches the basic typographic resolution).
290290
291291For comparison: Windows native DPI is 96. You can read more about history of this difference [here](https://en.wikipedia.org/wiki/Dots_per_inch#Computer_monitor_DPI_standards)
292292
293293In order to achieve the ease of use and design for cross-platform applications, Cocoa (screen) DPI is also emulated (by LCL) to be at 96 dpi. What that actually means is that font sizes between LCL applications and macOS native applications will be different (at roughly 33%).
294294
295295![](/wiki-images/6/6b/CarbonFontWrong.png)
296296
297297This can be adjusted by changing the **CocoaBasePPI** variable at run time.
298298
299299### Font Enumeration
300300
301301To implement windows-like font enumeration, two NSFontManager methods are used
302302
303303
304304**availableFontFamilies** - to get the list of families
305305
306306**availableMembersOfFontFamily:** - to get the list of available styles for fonts
307307
308308Input parameters recognized:
309309
310310- todo: **lfFaceName** - the case-insensitive, exact name match.
311311-
312312
313313## Handles
314314
315315The following objects are used to implement HANDLEs for graphical objects
316316
317317**LCL Handle**
318318
319319**Cocoa WS Class**
320320
321321**Notes**
322322
323323HICON
324324
325325TCocoaBitmap
326326
327327HPEN
328328
329329TCocoaPen
330330
331331HBRUSH
332332
333333TCocoaBrush
334334
335335HRGN
336336
337337TCocoaRegion
338338
339339HCURSOR
340340
341341TCocoaCursor
342342
343343TCocoaCursor doesn't inherit from TCocoaBitmap)
344344
345345HBITMAP
346346
347347TCocoaBitmap
348348
349349TBitmap.Canvas.Handle
350350
351351TCocoaBitmapContext
352352
353353The key difference from TCocoaContext is that after any changes to bitmap context, the underlying image itself is invalidated.
354354
355355This is necessary for Windows like behavior. (macOS image objects are immutable, but windows bitmaps are)
356356
357357TControl.Canvas.Handle
358358
359359TCocoaContext
360360
361361## Bitmap
362362
363363**TCocoaBitmap** implements the internal bitmap handle.
364364
365365### Change Tracking
366366
367367In order for a bitmap (a 2d-array of pixel values) to be drawn, a NSBitmapImageRep object.
368368
369369The NSBitmapImageRep is immutable. Its contents cannot be changed after the initial drawing (the pixel values seems it be copied within Cocoa).
370370
371371If a Bitmap contents was modified (i.e. by using (Canvas) Drawing methods or by direct access via ScanLine), the bitmap must re-create NSBitmapImageRep before the next drawing.
372372
373373The SetModified() marks the Bitmap as modified. TCocoaBitmapContext (Device Context created for a Bitmap) would mark the bitmap as modified on any draw method.
374374
375375### Scan Lines
376376
377377For PixelFormat 32-bit the pixel format is as following:
378378
379-```
379+```text
380380$BBGGRRAA
381381$ff0000ff - all blue
382382$00ff00ff - all green
383383$0000ffff - all red
384384$000000ff - all black (alpha channel only)
385385$ffffff00 - fully transparent
386386```
387387
388388## Forced Repaint
389389
390390There's an additional code added for processing **DrawRect** event. If a control was resized during a draw rect, then the resulting graphics output could be corrupted. [32970](https://bugs.freepascal.org/view.php?id=32970)
391391
392392As an example TTreeView component could be used. It updates scroll bars during the initial paint. The update of scroll bars is causing a client rectangle to be changed, causing a glitch when drawing the control for the first time
393393
394394Naturally, the next repaint fixes the problem right away.
395395
396396![](/wiki-images/7/7c/CocoaInvalidTree.png) ![](/wiki-images/d/db/CocoaValidTree.png)
397397
398398Sending another event into Cocoa event queue, to repaint the control again would cause flickering and yet bad user experience. Forcefully calling for a repaint one more time seems to be resolving the problem, while potentially is an overhead due to double job done.
399399
400400Also double drawing could cause artifacts on controls that are using any sorts of transparency:
401401
402402![](/wiki-images/e/e7/TransperancyDoubleDraw.png)
403403
404404The best solution is to avoid changing of the control bounds at all during drawing operation.
405405
406406## Theme Drawing
407407
408408HITheme API is deprecated by Apple together with Carbon. It's still available in OS X, but for i386 only. It will presumably be completely removed on 64-bit only macOS.
409409
410410However, some LCL controls cannot be mapped to existing Cocoa provided controls and thus might require some "custom drawing". The drawing should look system native though. In order to achieve that the NSCell family could be used. NSCell allows drawing (hit-test and as well as handle user input) for OS X native elements. If Apple changes the appearance of controls (cells), the LCL application would "pick-up" the look automatically.
411411
412412**Deprecated? macOS version specific?** In order to be drawn NSCells require the presence of NSView, thus it's hard to use them for the implementation of LCL TTheme APIs. NSView doesn't seem to be required. At least NSCell operates without the presence NSView. However, per Apple's documentation it's mentioned that the drawing would occur in a "focused" control. That helps to use NSCell for on-screen drawing, but is a big question for bitmap drawing.
413413
414414Example of NSCell usage is CocoaStatusBar drawing.
415415
416416It might be that Apple moves away from using NSCell. The class itself is not yet deprecated, even though Apple suggests that NSView should be used more extensively.
417417
418418## See Also
419419
420420- [[Cocoa Internals]]
421421- [Introduction to Color Programming Topics for Cocoa](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DrawColor/DrawColor.html)
422422
423423---
424424*From the Free Pascal wiki, page "Cocoa Internals/Graphics", as it stood on 2022-05-31 after a change by Skalogryz, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
425425Category: Cocoa
426426Category: macOS

Back to history