%%
%% This is file `concrete-vec.sty'.
%%
%% Copyright (C) 2026 Matthew Lorig
%%
%% This work may be distributed and/or modified under the conditions of
%% the LaTeX Project Public License, either version 1.3c of this license
%% or (at your option) any later version.  The latest version of this
%% license is in http://www.latex-project.org/lppl.txt and version 1.3c
%% or later is part of all distributions of LaTeX version 2008 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%% The Current Maintainer of this work is Matthew Lorig.
%%
%% This work consists of the files concrete-vec.sty and concrete-vec.tex
%% and the derived file concrete-vec.pdf.
%%
\NeedsTeXFormat{LaTeX2e}[2020/10/01]
\ProvidesPackage{concrete-vec}
  [2026/07/24 v1.2 Concrete text and maths as outlines, with simulated bold]

\RequirePackage{kvoptions}
\RequirePackage{etoolbox}

\SetupKeyvalOptions{family=ccv,prefix=ccv@}

% ---------------------------------------------------------------------
%  Options
% ---------------------------------------------------------------------
\DeclareBoolOption[true]{bold}
\DeclareComplementaryOption{nobold}{bold}
\DeclareStringOption[0.03em]{boldwidth}
\DeclareBoolOption[false]{mathbold}
\DeclareComplementaryOption{nomathbold}{mathbold}
\DeclareBoolOption[true]{math}
\DeclareComplementaryOption{nomath}{math}
\DeclareBoolOption[true]{lmodern}
\DeclareComplementaryOption{nolmodern}{lmodern}
\DeclareBoolOption[true]{frenchmath}
\DeclareComplementaryOption{nofrenchmath}{frenchmath}
\DeclareStringOption[lgr]{greek}
% Unrecognised options are handed on to mathastext, so that e.g.
% [italic] or [subdued] may be given directly to this package.
\DeclareDefaultOption{\PassOptionsToPackage{\CurrentOption}{mathastext}}
\ProcessKeyvalOptions*

\newcommand*\ccv@warn{\PackageWarning{concrete-vec}}
\newcommand*\ccv@err{\PackageError{concrete-vec}}
\def\ccv@ccr{ccr}

% ---------------------------------------------------------------------
%  1. Output encoding
%
%  Only the T1/TS1-encoded Concrete fonts (bundle `ecc') have freely
%  available Type 1 outlines, supplied by `cm-super'.  In OT1 the fonts
%  exist as METAFONT sources only and pdfTeX embeds bitmaps.
% ---------------------------------------------------------------------
\PassOptionsToPackage{T1}{fontenc}
\RequirePackage{fontenc}
\def\ccv@Tone{T1}
\AtBeginDocument{%
  \ifx\encodingdefault\ccv@Tone\else
    \ccv@warn{Default text encoding is `\encodingdefault', not T1.%
      \MessageBreak The Concrete fonts have Type 1 outlines only in%
      \MessageBreak T1/TS1; expect bitmap fonts in the output}%
  \fi
}

% ---------------------------------------------------------------------
%  2. Text families
%
%  Concrete has no sans serif or typewriter companion.  Latin Modern is
%  a safe outline default for those, and supplies outline symbol and
%  extension fonts for maths, which mathastext does not replace.
% ---------------------------------------------------------------------
\ifccv@lmodern
  \RequirePackage{lmodern}
\fi
\renewcommand*\rmdefault{ccr}

% ---------------------------------------------------------------------
%  3. Bold shapes
%
%  t1ccr.fd silently substitutes T1/ccr/bx/* by Computer Modern bold, so
%  \textbf in an otherwise Concrete document quietly changes typeface,
%  while T1/ccr/b/* is undefined, so \bfseries yields no weight at all.
%  Point every bold shape back at the medium Concrete one; the weight is
%  then supplied by stroking (section 4).  The .fd file must have been
%  read before these declarations, hence the dummy font selection.
% ---------------------------------------------------------------------
\ifccv@bold
  \begingroup
    \fontencoding{T1}\fontfamily{ccr}\fontseries{m}\fontshape{n}\selectfont
  \endgroup
  \begingroup
    \let\@font@info\@gobble
    \DeclareFontShape{T1}{ccr}{b}{n}{<->ssub*ccr/m/n}{}%
    \DeclareFontShape{T1}{ccr}{b}{it}{<->ssub*ccr/m/it}{}%
    \DeclareFontShape{T1}{ccr}{b}{sl}{<->ssub*ccr/m/sl}{}%
    \DeclareFontShape{T1}{ccr}{b}{sc}{<->ssub*ccr/m/sc}{}%
    \DeclareFontShape{T1}{ccr}{bx}{n}{<->ssub*ccr/m/n}{}%
    \DeclareFontShape{T1}{ccr}{bx}{it}{<->ssub*ccr/m/it}{}%
    \DeclareFontShape{T1}{ccr}{bx}{sl}{<->ssub*ccr/m/sl}{}%
    \DeclareFontShape{T1}{ccr}{bx}{sc}{<->ssub*ccr/m/sc}{}%
  \endgroup
\fi

% ---------------------------------------------------------------------
%  4. Simulated bold
%
%  PDF text rendering mode 2 fills *and* strokes each glyph, so a medium
%  outline font gains weight from a suitable stroke width.  The default,
%  0.03em, is 0.3pt at 10pt and follows the type size.  The same idea is
%  packaged independently by Herbert Voss as `xfakebold'.
% ---------------------------------------------------------------------
\ifccv@bold
  \RequirePackage{pdfrender}

  \newcommand*\setconcreteboldwidth[1]{\renewcommand*\ccv@boldwidth{#1}}

  \DeclareRobustCommand*\concretebold{%
    \pdfrender{TextRenderingMode=FillStroke,LineWidth=\ccv@boldwidth}}
  \DeclareRobustCommand*\concretenobold{%
    \pdfrender{TextRenderingMode=Fill}}

  % Stroke only where the current family really is Concrete, so that
  % \textsf and \texttt keep their genuine bold designs.
  \newcommand*\ccv@autobold{\ifx\f@family\ccv@ccr\concretebold\fi}

  \apptocmd{\bfseries}{\ccv@autobold}{}{%
    \ccv@warn{Could not patch \string\bfseries;\MessageBreak
      simulated bold is available only via \string\concretebold}}
  \apptocmd{\mdseries}{\concretenobold}{}{%
    \ccv@warn{Could not patch \string\mdseries}}
  \apptocmd{\normalfont}{\concretenobold}{}{%
    \ccv@warn{Could not patch \string\normalfont}}
\else
  \newcommand*\setconcreteboldwidth[1]{}
  \DeclareRobustCommand*\concretebold{}
  \DeclareRobustCommand*\concretenobold{}
\fi

% ---------------------------------------------------------------------
%  5. Maths
%
%  mathastext reuses the current text font for the letters, digits and
%  operators of maths mode; that is what makes Concrete maths available
%  as outlines at all.  Delimiters, large operators and the symbol fonts
%  are left to Latin Modern (or Computer Modern) and are outlines too.
% ---------------------------------------------------------------------
\newif\ifccv@amsmath@seen
\@ifpackageloaded{amsmath}{\ccv@amsmath@seentrue}{}%
\ifccv@math
  \ifccv@frenchmath
    \PassOptionsToPackage{frenchmath}{mathastext}%
  \fi
  % Keep mathastext's hands off \mathbf when we intend to redefine it,
  % otherwise it reclaims the control sequence at first math activation.
  \ifccv@bold\ifccv@mathbold
    \PassOptionsToPackage{defaultbf}{mathastext}%
  \fi\fi
  \def\ccv@tmp{lgr}%
  \ifx\ccv@greek\ccv@tmp \PassOptionsToPackage{LGRgreek}{mathastext}\else
  \def\ccv@tmp{euler}%
  \ifx\ccv@greek\ccv@tmp \PassOptionsToPackage{eulergreek}{mathastext}\else
  \def\ccv@tmp{symbol}%
  \ifx\ccv@greek\ccv@tmp \PassOptionsToPackage{symbolgreek}{mathastext}\else
  \def\ccv@tmp{none}%
  \ifx\ccv@greek\ccv@tmp \else
    \ccv@err{Unknown value `\ccv@greek' for option greek}%
      {Permitted values are lgr, euler, symbol and none.}%
  \fi\fi\fi\fi

  \RequirePackage{mathastext}

  % There is no LGR-encoded Concrete, so LGRgreek falls back to the CB
  % Greek fonts.  Declaring that substitution explicitly makes it
  % silent; the CB fonts do have Type 1 outlines.
  \def\ccv@tmp{lgr}%
  \ifx\ccv@greek\ccv@tmp
    \@ifundefined{T@LGR}{}{\DeclareFontFamilySubstitution{LGR}{ccr}{cmr}}%
  \fi

  % mathastext expects to be the last maths package loaded.
  \AtBeginDocument{%
    \@ifpackageloaded{amsmath}{%
      \ifccv@amsmath@seen\else
        \ccv@warn{amsmath was loaded after concrete-vec.\MessageBreak
          Load concrete-vec last, after amsmath and friends}%
      \fi
    }{}%
  }
\fi

% ---------------------------------------------------------------------
%  6. Bold in maths: \bd and \mathbold
%
%  \mathbf bolds only the Latin letters a-z, A-Z and forces them upright,
%  so \mathbf{\pi} fails and \mathbf{x} loses the italic.  \bd instead
%  strokes its argument *in place*: the glyph keeps whatever shape it
%  already has (the italic x stays italic, \pi is really \pi), and any
%  symbol works, not just letters.  This is the recommended way to get a
%  bold letter -- Latin or Greek -- in mathematics.
%
%    \bd{x}       italic x, thickened      \bd{\pi}   pi, thickened
%    \bd{\Gamma}  upright Gamma, thickened \bd{\mathbf{v}}  upright bold v
%
%  \mathbold is a synonym kept for continuity; it also strokes a whole
%  subformula, e.g. \mathbold{\alpha+\sum_i x_i}.
%
%  \mathbf is left untouched by default, so it remains the standard
%  upright Latin bold alphabet for anyone who wants it.  Passing the
%  package option [mathbold] additionally reroutes \mathbf through the
%  stroke, for backward compatibility with earlier versions.
% ---------------------------------------------------------------------
\ifccv@bold
  % \bd bolds in either mode: ordinary bold in text, in-place stroke in
  % maths (so a symbol keeps its shape and any glyph works, not just
  % letters).  In text it just calls \textbf, whose Concrete weight the
  % package already supplies via the \bfseries patch (section 4).
  \DeclareRobustCommand\bd[1]{\ifmmode{\concretebold #1}\else\textbf{#1}\fi}
  \newcommand*\mathbold[1]{{\concretebold #1}}
  \ifccv@mathbold\ifccv@math
    % Optional: make \mathbf itself stroke, in place, preserving shape.
    % NFSS rewrites a maths-alphabet control sequence when its version is
    % first activated, so we finalise every alphabet inside a discarded
    % box and only then override \mathbf with a plain stroking macro.
    \AddToHook{begindocument/end}{%
      \setbox\z@\hbox{$\mathnormal{}\mathrm{}\mathbf{}\mathit{}%
        \mathsf{}\mathtt{}$}%
      \protected\def\mathbf#1{{\concretebold #1}}%
      \providecommand*\boldsymbol[1]{{\concretebold #1}}%
    }%
  \fi\fi
\else
  \DeclareRobustCommand\bd[1]{#1}%
  \newcommand*\mathbold[1]{#1}%
\fi

\endinput
%%
%% End of file `concrete-vec.sty'.
