mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
Cocoa рисует канву в физических пикселях, TBitmap всегда 1x, поэтому кадр,
собранный в offscreen-битмап логического размера, растягивался вдвое.
PlatformUtils.GetScreenScale возвращает 2 на Retina и 1 на остальных
платформах. Масштаб — обычная переменная, а не условная компиляция: на
Windows/Linux умножение на 1 даёт прежние числа, а на канву кадр кладётся
через Draw, как и раньше (StretchDraw только при масштабе > 1).
В SMeterView, RulerView и PanZoomBar битмап растёт в S раз, пиксельные
константы, размеры шрифтов и толщина пера умножаются на S. Перо важно
отдельно: иначе на Retina все риски стали бы вдвое тоньше.
RulerView кэширует битмап, поэтому смена масштаба сбрасывает кэш.
PanZoomBar.ThumbGeom получил параметр AScale: отрисовка зовёт его с
физической шириной, хит-тест мыши — с логической, код мыши не менялся.
Objective-C изолирован в MacScale.pas: {$MODESWITCH OBJECTIVEC1} несовместим
с {$MODE Delphi}, а DWARF-3 (-gw3, Debug-режим lazbuild) роняет FPC 3.2.4 с
internal error 200609171 на любых Objective-C типах — отсюда {$DEBUGINFO OFF}.
Замер после правки: 37.5% CPU против 38% базовых, отрисовка этих трёх
элементов ниже уровня шума в профиле.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87 lines
2.6 KiB
ObjectPascal
87 lines
2.6 KiB
ObjectPascal
unit PlatformUtils;
|
|
|
|
{
|
|
PlatformUtils.pas - small helpers for desktop/runtime platform checks.
|
|
}
|
|
|
|
{$IFDEF FPC}
|
|
{$MODE Delphi}
|
|
{$ENDIF}
|
|
|
|
interface
|
|
|
|
function HasOpenGLSpectrumSwitch: Boolean;
|
|
function CurrentScreenDPI: Integer;
|
|
// Целочисленный масштаб канвы экрана: 2 на Retina, 1 везде остальном.
|
|
// Windows/Linux всегда получают 1 ⇒ умножение на него ничего не меняет.
|
|
function GetScreenScale: Integer;
|
|
// Возвращает каталог для хранения конфигурации (с завершающим разделителем).
|
|
// macOS: ~/Library/Application Support/ewsdr/
|
|
// Linux: ~/.config/ewsdr/
|
|
// Windows: %APPDATA%\ewsdr\
|
|
function GetAppCfgDir: string;
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils {$IFNDEF HEADLESS}, Forms{$ENDIF}
|
|
{$IF DEFINED(DARWIN) AND NOT DEFINED(HEADLESS)}, MacScale{$ENDIF};
|
|
|
|
function HasOpenGLSpectrumSwitch: Boolean;
|
|
var
|
|
I: Integer;
|
|
S: string;
|
|
begin
|
|
Result := False;
|
|
for I := 1 to ParamCount do
|
|
begin
|
|
S := LowerCase(ParamStr(I));
|
|
if (S = '--opengl') or (S = '-opengl') or (S = '/opengl') then
|
|
Exit(True);
|
|
end;
|
|
// Бандл под LaunchServices не может передать argv, поэтому тот же
|
|
// переключатель читается из окружения (Info.plist -> LSEnvironment).
|
|
S := LowerCase(Trim(GetEnvironmentVariable('EWSDR_OPENGL')));
|
|
if (S = '1') or (S = 'true') or (S = 'yes') or (S = 'on') then
|
|
Exit(True);
|
|
end;
|
|
|
|
function GetScreenScale: Integer;
|
|
begin
|
|
{$IF DEFINED(DARWIN) AND NOT DEFINED(HEADLESS)}
|
|
// Cocoa рисует канву в физических пикселях, а TBitmap всегда 1x. Кто рисует
|
|
// через offscreen-битмап, должен растить его в GetScreenScale раз.
|
|
Result := MacBackingScale;
|
|
{$ELSE}
|
|
Result := 1;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function CurrentScreenDPI: Integer;
|
|
begin
|
|
{$IFNDEF HEADLESS}
|
|
Result := Screen.PixelsPerInch;
|
|
if Result <= 0 then Result := 96;
|
|
{$ELSE}
|
|
Result := 96; // headless-демон без LCL: экрана нет, дефолт DPI
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function GetAppCfgDir: string;
|
|
begin
|
|
{$IFDEF WINDOWS}
|
|
Result := GetEnvironmentVariable('APPDATA');
|
|
if Result = '' then
|
|
Result := GetEnvironmentVariable('LOCALAPPDATA');
|
|
if Result = '' then
|
|
Result := ExtractFilePath(ParamStr(0));
|
|
Result := IncludeTrailingPathDelimiter(Result) + 'ewsdr' + PathDelim;
|
|
{$ELSE}
|
|
Result := IncludeTrailingPathDelimiter(GetAppConfigDir(False));
|
|
{$ENDIF}
|
|
if not DirectoryExists(Result) then
|
|
ForceDirectories(Result);
|
|
end;
|
|
|
|
end.
|