Вот мой главный претендент на тормоза для русских текстов. Тут мы видим, что ширина первых 255 символов юникода кэширована, а для остальных нет!
Код:
(* width methods for unicode *)
PROCEDURE (f: Font) wTab* (dc: WinApi.HANDLE; ch: CHAR): INTEGER, NEW;
VAR res, w: INTEGER; abc: ARRAY 1 OF WinApi.ABC; wt: ARRAY 1 OF INTEGER;
BEGIN
IF ch < 100X THEN RETURN f.wtab[ORD(ch)] END;
res := WinApi.GetCharABCWidthsW(dc, ORD(ch), ORD(ch), abc[0]);
IF res # 0 THEN
w := abc[0].abcA + abc[0].abcB + abc[0].abcC;
w := w * f.a DIV grid + w * f.b
ELSE
res := WinApi.GetCharWidth32W(dc, ORD(ch), ORD(ch), wt[0]);
IF res # 0 THEN w := wt[0] * f.a DIV grid + wt[0] * f.b
ELSE
res := WinApi.GetCharWidthW(dc, ORD(ch), ORD(ch), wt[0]);
IF res # 0 THEN w := wt[0] * f.a DIV grid + wt[0] * f.b
ELSE w := f.wtab[1]
END
END
END;
RETURN w
END wTab;
PROCEDURE (f: Font) fTab* (dc: WinApi.HANDLE; ch: CHAR): INTEGER, NEW;
VAR res, w: INTEGER; abc: ARRAY 1 OF WinApi.ABC;
BEGIN
IF ch < 100X THEN RETURN f.ftab[ORD(ch)] END;
res := WinApi.GetCharABCWidthsW(dc, ORD(ch), ORD(ch), abc[0]);
IF (res # 0) & (abc[0].abcA < 0) THEN
w := -abc[0].abcA;
w := w * f.a DIV grid + w * f.b
ELSE w := 0
END;
RETURN w
END fTab;
PROCEDURE (f: Font) tTab* (dc: WinApi.HANDLE; ch: CHAR): INTEGER, NEW;
VAR res, w: INTEGER; abc: ARRAY 1 OF WinApi.ABC;
BEGIN
IF ch < 100X THEN RETURN f.ttab[ORD(ch)] END;
res := WinApi.GetCharABCWidthsW(dc, ORD(ch), ORD(ch), abc[0]);
IF (res # 0) & (abc[0].abcC < 0) THEN
w := -abc[0].abcC;
w := w * f.a DIV grid + w * f.b
ELSE w := 0
END;
RETURN w
END tTab;
PROCEDURE (df: DevFont) wTab* (dc: WinApi.HANDLE; ch: CHAR): INTEGER, NEW;
VAR res, w: INTEGER; wt: ARRAY 1 OF INTEGER;
BEGIN
IF ch < 100X THEN RETURN df.wtab[ORD(ch)] END;
res := WinApi.GetCharWidth32W(dc, ORD(ch), ORD(ch), wt[0]);
IF res = 0 THEN res := WinApi.GetCharWidthW(dc, ORD(ch), ORD(ch), wt[0]) END;
IF res # 0 THEN w := wt[0] ELSE w := df.wtab[1] END;
RETURN w
END wTab;