Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public GlyphsSerializer(GlyphRun glyphRun)
_advances = glyphRun.AdvanceWidths;
_offsets = glyphRun.GlyphOffsets;

_advanceWidthRoundingError = 0.0;
_currentAdvanceTotal = 0.0;
_idealAdvanceTotal = 0.0;

// "100,50,,0;".Length is a capacity estimate for an individual glyph
_glyphStringBuider = new StringBuilder(10);
Expand All @@ -84,7 +85,8 @@ public GlyphsSerializer(GlyphRun glyphRun)
/// </summary>
public void ComputeContentStrings(out string characters, out string indices, out string caretStops)
{
_advanceWidthRoundingError = 0.0;
_currentAdvanceTotal = 0.0;
_idealAdvanceTotal = 0.0;

if (_clusters != null)
{
Expand Down Expand Up @@ -188,13 +190,28 @@ private void AddGlyph(int glyph, int sourceCharacter)
_glyphStringBuider.Append(GlyphSubEntrySeparator);

// advance width
double unroundedAdvance = _advances[glyph] * _milToEm;
int normalizedAdvance = (int)Math.Round(unroundedAdvance + _advanceWidthRoundingError);
_advanceWidthRoundingError += (unroundedAdvance - (double)normalizedAdvance);
// #7499 Advance width needs to be specified if it differs from what is in the font tables. [ECMA-388 O5.5]
// Most commonly it differs after shaping, e.g. when kerning is applied. (Ex. 12-15)
// XPS supports floating point values, but in the interest of file size, we want to specify integers.

double shapingAdvance = _advances[glyph] * _milToEm;
double fontAdvance = _sideways ? _glyphTypeface.AdvanceHeights[fontIndex] : _glyphTypeface.AdvanceWidths[fontIndex];
if (normalizedAdvance != (int)Math.Round(fontAdvance * EmScaleFactor))

// To minimize rounding errors, we keep track of the unrounded advance total as required by [M5.6].
int roundedShapingAdvance = (int)Math.Round(_idealAdvanceTotal + shapingAdvance - _currentAdvanceTotal);
int roundedFontAdvance = (int)Math.Round(fontAdvance);

if (roundedShapingAdvance != roundedFontAdvance)
{
_glyphStringBuider.Append(normalizedAdvance.ToString(CultureInfo.InvariantCulture));
_glyphStringBuider.Append(roundedShapingAdvance.ToString(CultureInfo.InvariantCulture));
_currentAdvanceTotal += roundedShapingAdvance;
_idealAdvanceTotal += shapingAdvance;
}
else
{
// when the value comes from the font tables, the specification does not mandate clients to do any rounding
_currentAdvanceTotal += fontAdvance;
_idealAdvanceTotal += fontAdvance;
}

_glyphStringBuider.Append(GlyphSubEntrySeparator);
Expand Down Expand Up @@ -326,7 +343,9 @@ private string CreateCaretStopsString()

private int _glyphClusterInitialOffset;

private double _advanceWidthRoundingError;
private double _currentAdvanceTotal;

private double _idealAdvanceTotal;

private IList<ushort> _clusters;

Expand Down