Files
whetstone_DSL/editor/src/IconTypographyHarmonizer.h

61 lines
1.9 KiB
C++

#pragma once
// Step 518: Icon + Typography Contrast Harmonization
#include <string>
#include <vector>
#include <algorithm>
struct TypographyProfile {
float bodySizePx = 14.0f;
float headingSizePx = 20.0f;
float lineHeight = 1.4f;
float weightBody = 450.0f;
float weightHeading = 640.0f;
float textContrast = 1.0f;
};
struct IconProfile {
float strokePx = 1.5f;
float contrast = 1.0f;
float opticalSize = 16.0f;
};
class IconTypographyHarmonizer {
public:
static TypographyProfile darkSurfaceTypography(float density) {
float d = std::max(0.8f, std::min(1.4f, density));
TypographyProfile t;
t.bodySizePx = 14.0f * d;
t.headingSizePx = 20.0f * d;
t.lineHeight = 1.38f;
t.weightBody = 460.0f;
t.weightHeading = 650.0f;
t.textContrast = 6.4f;
return t;
}
static IconProfile iconProfileFor(float density, bool emphasized) {
float d = std::max(0.8f, std::min(1.4f, density));
IconProfile i;
i.strokePx = emphasized ? 1.9f * d : 1.5f * d;
i.contrast = emphasized ? 4.5f : 3.4f;
i.opticalSize = 16.0f * d;
return i;
}
static bool harmonized(const TypographyProfile& t, const IconProfile& i) {
return t.textContrast >= 4.5f && i.contrast >= 3.0f &&
i.strokePx >= 1.0f && t.headingSizePx > t.bodySizePx;
}
static float rhythmScore(const TypographyProfile& t,
const std::vector<float>& panelDensities) {
if (panelDensities.empty()) return 0.0f;
float spread = *std::max_element(panelDensities.begin(), panelDensities.end()) -
*std::min_element(panelDensities.begin(), panelDensities.end());
float base = 1.0f - std::min(1.0f, spread / 12.0f);
float typeBonus = (t.lineHeight >= 1.3f && t.lineHeight <= 1.6f) ? 0.2f : 0.0f;
return std::max(0.0f, std::min(1.0f, base + typeBonus));
}
};