Skip to content
Topaz6.0 · Before release
Download

Search documentation

Specification 6.0 · Not released · Tested product 5.21.3

Use arrow keys to choose a result. Press Enter to open.

Type an API name, diagnostic number, rule, or project topic.

    Library · std.typeset

    JustificationPolicy.cjkStretchRatio

    Inspect the declaration, parameters, and availability of this API.

    JustificationPolicy.cjkStretchRatio: float
    Receiver
    JustificationPolicy
    Minimum arity
    0
    Maximum arity
    0

    Declaration and parameters

    Link

    Availability

    Included by default: Pending

    Import std.typeset in language mode 5.21.

    The current compiler selects std/typeset.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.

    Source evidence

    Receiver

    JustificationPolicy

    Parameter constraints

    JustificationPolicy describes how FixedPoint scores a measured line. It does not change text, insert glyphs, or create break opportunities. Constructing the record does not run validation. breakParagraph validates it before measuring items.

    minGapCount, minLineWidthRatioM, maxGapRatioR, and a present minFinalLineWidthRatioM must be nonnegative. maxAdjustment and maxGapAdjustment must be nonnegative point lengths. cjkStretchRatio must be finite and nonnegative. Violations return TypesetError.InvalidPolicy with an explanatory string.

    The width ratio fields use 1000 for one whole target width. maxGapRatioR uses 100000000 for a ratio of one. These ratios have no additional upper bound. A threshold above the attainable width can increase cost without making the policy malformed.

    A present LatinSpacing value follows its typed length contract. minWordSpaceRatio ranges from 0.8 through 1.0. maxWordSpaceRatio ranges from 1.0 through 1.33. maxLetterSpacingEm ranges from 0em through 0.015em and fontSizePt is positive. Both float ratios must be finite. Invalid values return TypesetError.InvalidPolicy even when the selected model does not use their capacities.

    Unjustified contributes zero justification cost and supplies no inferred spacing capacity. LatinWordSpace scores eligible word spaces. CjkInterCharacter also recognizes eligible boundaries between single CJK units. All policy fields are validated in every mode.

    KnuthPlass computes its adjustment ratio from the supplied Glue stretch and shrink values. JustificationPolicy does not alter that ratio or its demerits. The policy still undergoes validation. The KnuthPlass policy defines tolerance and line costs.

    For FixedPoint, a present LatinSpacing value takes precedence when the trimmed line contains Latin letter units without other alphabetic scripts, or contains a recognized single CJK unit. The inferred capacity replaces the fallback minimum gap count, minimum nonfinal width, total adjustment, per gap adjustment, and gap ratio tests for that line.

    Inferred shrink capacity is the floor of the total U+0020 unit width multiplied by one minus minWordSpaceRatio. Stretch capacity adds three separately evaluated contributions. They are the floor of that space width multiplied by maxWordSpaceRatio minus one, the eligible Latin letter gap count multiplied by the resolved typed letter maximum, and the floor of the eligible CJK width multiplied by cjkStretchRatio. The CJK contribution is zero in LatinWordSpace mode.

    An inferred Latin letter unit contains an Alphabetic scalar and has every scalar in U+0041 through U+024F, U+0300 through U+036F, or U+1E00 through U+1EFF. A letter gap joins two adjacent such units. A CJK capacity contribution uses the left width of adjacent single CJK units. Resolve the typed letter maximum with the explicit font size before grid conversion. Preserve each independent floor for dimensionless word and CJK ratios.

    Without an inferred capacity, word gaps are units whose complete text is U+0020. CJK gaps join adjacent recognized single CJK units and count both sides of an intervening U+0020 or U+00A0 unit. Recognized CJK scalars are U+1100 through U+11FF, U+3130 through U+318F, U+3400 through U+4DBF, U+4E00 through U+9FFF, U+AC00 through U+D7A3, and U+F900 through U+FAFF. Punctuation does not provide a CJK gap.

    The fallback nonfinal calculation first scores a line below minLineWidthRatioM. It then checks the total positive adjustment against maxAdjustment. LatinWordSpace uses minGapCount and maxGapAdjustment on word gaps. CjkInterCharacter uses word gaps when present and otherwise uses CJK gaps, minGapCount, maxGapAdjustment, and maxGapRatioR. Falling short raises the justification cost rather than returning an input error.

    FixedPoint calculations use the millipoint grid. A total positive adjustment of at most one millipoint has zero fallback cost. For a larger adjustment, maxAdjustment is the exact total bound. Per gap checks tolerate one millipoint per gap. The CJK ratio comparison tolerates 100000 units of maxGapRatioR. These allowances do not add spacing to the returned text.

    For a final FixedPoint line in a justified mode, None() in minFinalLineWidthRatioM contributes zero justification cost. Some supplies a minimum final width ratio and applies to that final line. It never replaces the nonfinal checks. Compare the attainable width after the permitted positive adjustment with the target times the ratio divided by 1000, rounded halfway upward.

    For that final threshold, attainable width adds inferred stretch when available. Otherwise it adds the smaller of maxAdjustment and the word gap count times maxGapAdjustment. Meeting the threshold contributes zero. A shortfall contributes 25000000000 plus the halfway upward rounded shortfall times 1000000 divided by the target, multiplied by 1000000.

    The optimized FixedPoint planner can try a pass that requires bounded fill before its ordinary pass. The paragraph plan reports whether that pass succeeded. A returned plan does not distribute the requested adjustment into the original units. Consumers use the reported widths and the selected policy when rendering.

    When the exact nonfinal minimum width comparison fails, the scoring shortfall is target minus natural width, with a minimum of zero. Scale that shortfall by 1000000, divide by target with halfway upward rounding, then multiply by 1000000 for LatinWordSpace or 100000 for CjkInterCharacter. Add 25000000000 to this nonnegative contribution. These operations use checked arithmetic.

    For every FixedPoint justification comparison, natural width is the trimmed text width plus selectedPenaltyWidth. The target remains PlanLine.target. A selected insertion supplies no word gap, CJK gap, letter gap, stretch, or shrink capacity.

    Result

    The declared result type is float.

    Effects

    Failures

    Result and effects

    Link

    Select this field from a value of its named type without call parentheses.

    Multiply eligible CJK width by this finite nonnegative ratio when inferring capacity in CjkInterCharacter mode.

    Why

    Link

    Policy validation and explicit precedence give every field one defined effect.

    Resolved contracts

    Link

    Related entries

    Link

    std.typeset

    Score justification with explicit policy precedence

    Link
    Ruletopaz.stdlib.contract.typeset-justification.rule

    Score justification with explicit policy precedence

    JustificationPolicy describes how FixedPoint scores a measured line. It does not change text, insert glyphs, or create break opportunities. Constructing the record does not run validation. breakParagraph validates it before measuring items.

    minGapCount, minLineWidthRatioM, maxGapRatioR, and a present minFinalLineWidthRatioM must be nonnegative. maxAdjustment and maxGapAdjustment must be nonnegative point lengths. cjkStretchRatio must be finite and nonnegative. Violations return TypesetError.InvalidPolicy with an explanatory string.

    The width ratio fields use 1000 for one whole target width. maxGapRatioR uses 100000000 for a ratio of one. These ratios have no additional upper bound. A threshold above the attainable width can increase cost without making the policy malformed.

    A present LatinSpacing value follows its typed length contract. minWordSpaceRatio ranges from 0.8 through 1.0. maxWordSpaceRatio ranges from 1.0 through 1.33. maxLetterSpacingEm ranges from 0em through 0.015em and fontSizePt is positive. Both float ratios must be finite. Invalid values return TypesetError.InvalidPolicy even when the selected model does not use their capacities.

    Unjustified contributes zero justification cost and supplies no inferred spacing capacity. LatinWordSpace scores eligible word spaces. CjkInterCharacter also recognizes eligible boundaries between single CJK units. All policy fields are validated in every mode.

    KnuthPlass computes its adjustment ratio from the supplied Glue stretch and shrink values. JustificationPolicy does not alter that ratio or its demerits. The policy still undergoes validation. The KnuthPlass policy defines tolerance and line costs.

    For FixedPoint, a present LatinSpacing value takes precedence when the trimmed line contains Latin letter units without other alphabetic scripts, or contains a recognized single CJK unit. The inferred capacity replaces the fallback minimum gap count, minimum nonfinal width, total adjustment, per gap adjustment, and gap ratio tests for that line.

    Inferred shrink capacity is the floor of the total U+0020 unit width multiplied by one minus minWordSpaceRatio. Stretch capacity adds three separately evaluated contributions. They are the floor of that space width multiplied by maxWordSpaceRatio minus one, the eligible Latin letter gap count multiplied by the resolved typed letter maximum, and the floor of the eligible CJK width multiplied by cjkStretchRatio. The CJK contribution is zero in LatinWordSpace mode.

    An inferred Latin letter unit contains an Alphabetic scalar and has every scalar in U+0041 through U+024F, U+0300 through U+036F, or U+1E00 through U+1EFF. A letter gap joins two adjacent such units. A CJK capacity contribution uses the left width of adjacent single CJK units. Resolve the typed letter maximum with the explicit font size before grid conversion. Preserve each independent floor for dimensionless word and CJK ratios.

    Without an inferred capacity, word gaps are units whose complete text is U+0020. CJK gaps join adjacent recognized single CJK units and count both sides of an intervening U+0020 or U+00A0 unit. Recognized CJK scalars are U+1100 through U+11FF, U+3130 through U+318F, U+3400 through U+4DBF, U+4E00 through U+9FFF, U+AC00 through U+D7A3, and U+F900 through U+FAFF. Punctuation does not provide a CJK gap.

    The fallback nonfinal calculation first scores a line below minLineWidthRatioM. It then checks the total positive adjustment against maxAdjustment. LatinWordSpace uses minGapCount and maxGapAdjustment on word gaps. CjkInterCharacter uses word gaps when present and otherwise uses CJK gaps, minGapCount, maxGapAdjustment, and maxGapRatioR. Falling short raises the justification cost rather than returning an input error.

    FixedPoint calculations use the millipoint grid. A total positive adjustment of at most one millipoint has zero fallback cost. For a larger adjustment, maxAdjustment is the exact total bound. Per gap checks tolerate one millipoint per gap. The CJK ratio comparison tolerates 100000 units of maxGapRatioR. These allowances do not add spacing to the returned text.

    For a final FixedPoint line in a justified mode, None() in minFinalLineWidthRatioM contributes zero justification cost. Some supplies a minimum final width ratio and applies to that final line. It never replaces the nonfinal checks. Compare the attainable width after the permitted positive adjustment with the target times the ratio divided by 1000, rounded halfway upward.

    For that final threshold, attainable width adds inferred stretch when available. Otherwise it adds the smaller of maxAdjustment and the word gap count times maxGapAdjustment. Meeting the threshold contributes zero. A shortfall contributes 25000000000 plus the halfway upward rounded shortfall times 1000000 divided by the target, multiplied by 1000000.

    The optimized FixedPoint planner can try a pass that requires bounded fill before its ordinary pass. The paragraph plan reports whether that pass succeeded. A returned plan does not distribute the requested adjustment into the original units. Consumers use the reported widths and the selected policy when rendering.

    When the exact nonfinal minimum width comparison fails, the scoring shortfall is target minus natural width, with a minimum of zero. Scale that shortfall by 1000000, divide by target with halfway upward rounding, then multiply by 1000000 for LatinWordSpace or 100000 for CjkInterCharacter. Add 25000000000 to this nonnegative contribution. These operations use checked arithmetic.

    For every FixedPoint justification comparison, natural width is the trimmed text width plus selectedPenaltyWidth. The target remains PlanLine.target. A selected insertion supplies no word gap, CJK gap, letter gap, stretch, or shrink capacity.

    Why

    A caller needs to know which spacing controls determine a line cost. Explicit capacity precedence keeps the two cost models predictable. A distinct final line threshold gives its name one meaning and preserves ordinary nonfinal checks.

    Source evidence

    Choose a justification mode explicitly

    Link
    main.tpzChoose a justification mode explicitlyOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. function name(mode: ts.JustificationMode) -> string {
    4. match (mode) {
    5. case Unjustified() => "unjustified"
    6. case LatinWordSpace() => "latin"
    7. case CjkInterCharacter() => "cjk"
    8. }
    9. }
    10. io.writeLine(name(ts.JustificationMode.Unjustified()))
    11. io.writeLine(name(ts.JustificationMode.LatinWordSpace()))
    12. io.writeLine(name(ts.JustificationMode.CjkInterCharacter()))
    Expected outputexit 0
    unjustified
    latin
    cjk
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. unjustified
    2. latin
    3. cjk
    Source evidence

    Reject a negative gap count even in Unjustified mode

    Link
    main.tpzReject a negative gap count even in Unjustified modeOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. let items: Array<ts.Item> = [
    4. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 10pt, trackingAfter: 0pt }),
    5. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    6. ]
    7. let input = ts.Paragraph {
    8. grid: ts.DistanceGrid.MilliPoint(),
    9. items: items,
    10. geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },
    11. justification: ts.JustificationPolicy {
    12. mode: ts.JustificationMode.Unjustified(), minGapCount: -1,
    13. minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),
    14. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    15. latinSpacing: None(), cjkStretchRatio: 0.0
    16. },
    17. costModel: ts.CostModel.FixedPoint(),
    18. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    19. }
    20. match (ts.breakParagraph(input)) {
    21. case Err(InvalidPolicy(_)) => io.writeLine("InvalidPolicy")
    22. case _ => io.writeLine("unexpected result")
    23. }
    Expected outputexit 0
    InvalidPolicy
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. InvalidPolicy
    Source evidence

    Reject a negative physical adjustment cap

    Link
    main.tpzReject a negative physical adjustment capOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. let items: Array<ts.Item> = [
    4. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 10pt, trackingAfter: 0pt }),
    5. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    6. ]
    7. let input = ts.Paragraph {
    8. grid: ts.DistanceGrid.MilliPoint(),
    9. items: items,
    10. geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },
    11. justification: ts.JustificationPolicy {
    12. mode: ts.JustificationMode.Unjustified(), minGapCount: 0,
    13. minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),
    14. maxAdjustment: -1pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    15. latinSpacing: None(), cjkStretchRatio: 0.0
    16. },
    17. costModel: ts.CostModel.FixedPoint(),
    18. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    19. }
    20. match (ts.breakParagraph(input)) {
    21. case Err(InvalidPolicy(_)) => io.writeLine("InvalidPolicy")
    22. case _ => io.writeLine("unexpected result")
    23. }
    Expected outputexit 0
    InvalidPolicy
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. InvalidPolicy
    Source evidence

    Reject a negative final line ratio

    Link
    main.tpzReject a negative final line ratioOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. let items: Array<ts.Item> = [
    4. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 10pt, trackingAfter: 0pt }),
    5. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    6. ]
    7. let input = ts.Paragraph {
    8. grid: ts.DistanceGrid.MilliPoint(),
    9. items: items,
    10. geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },
    11. justification: ts.JustificationPolicy {
    12. mode: ts.JustificationMode.Unjustified(), minGapCount: 0,
    13. minLineWidthRatioM: 0, minFinalLineWidthRatioM: Some(-1),
    14. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    15. latinSpacing: None(), cjkStretchRatio: 0.0
    16. },
    17. costModel: ts.CostModel.FixedPoint(),
    18. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    19. }
    20. match (ts.breakParagraph(input)) {
    21. case Err(InvalidPolicy(_)) => io.writeLine("InvalidPolicy")
    22. case _ => io.writeLine("unexpected result")
    23. }
    Expected outputexit 0
    InvalidPolicy
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. InvalidPolicy
    Source evidence

    Score an underfilled nonfinal line without changing measured text

    Link
    main.tpzScore an underfilled nonfinal line without changing measured textOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. import std.test
    4. function sample(justification: ts.JustificationPolicy) -> ts.ParagraphResult {
    5. let items: Array<ts.Item> = [
    6. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 4pt, trackingAfter: 0pt }),
    7. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false }),
    8. ts.Item.BoxItem(ts.Box { unitIndex: 1, text: "next", width: 4pt, trackingAfter: 0pt }),
    9. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 2, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    10. ]
    11. let input = ts.Paragraph {
    12. grid: ts.DistanceGrid.MilliPoint(),
    13. items: items,
    14. geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },
    15. justification: justification,
    16. costModel: ts.CostModel.FixedPoint(),
    17. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    18. }
    19. test.assertOk(ts.breakParagraph(input))
    20. }
    21. let natural = sample(ts.JustificationPolicy {
    22. mode: ts.JustificationMode.Unjustified(), minGapCount: 0,
    23. minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),
    24. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    25. latinSpacing: None(), cjkStretchRatio: 0.0
    26. })
    27. let justified = sample(ts.JustificationPolicy {
    28. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 1,
    29. minLineWidthRatioM: 900, minFinalLineWidthRatioM: None(),
    30. maxAdjustment: 2pt, maxGapAdjustment: 1pt, maxGapRatioR: 0,
    31. latinSpacing: None(), cjkStretchRatio: 0.0
    32. })
    33. io.writeLine("{justified.optimized.lines.length}")
    34. io.writeLine("{justified.optimized.lines[0].cost > natural.optimized.lines[0].cost}")
    35. io.writeLine("{justified.optimized.lines[1].cost == natural.optimized.lines[1].cost}")
    36. io.writeLine("{justified.optimized.lines[0].adjustmentRatioR}")
    Expected outputexit 0
    2
    true
    true
    0
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. 2
    2. true
    3. true
    4. 0
    Source evidence

    Apply the final line threshold to the final line

    Link
    main.tpzApply the final line threshold to the final lineOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. import std.test
    4. function sample(justification: ts.JustificationPolicy) -> ts.ParagraphResult {
    5. let items: Array<ts.Item> = [
    6. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 10pt, trackingAfter: 0pt }),
    7. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    8. ]
    9. let input = ts.Paragraph {
    10. grid: ts.DistanceGrid.MilliPoint(),
    11. items: items,
    12. geometry: ts.LineGeometry { bodyTarget: 20pt, firstTarget: 20pt, dropCapSpan: 0, dropCapInset: 0pt },
    13. justification: justification,
    14. costModel: ts.CostModel.FixedPoint(),
    15. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    16. }
    17. test.assertOk(ts.breakParagraph(input))
    18. }
    19. let unconstrained = sample(ts.JustificationPolicy {
    20. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 0,
    21. minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),
    22. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    23. latinSpacing: None(), cjkStretchRatio: 0.0
    24. })
    25. let constrained = sample(ts.JustificationPolicy {
    26. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 0,
    27. minLineWidthRatioM: 0, minFinalLineWidthRatioM: Some(1000),
    28. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    29. latinSpacing: None(), cjkStretchRatio: 0.0
    30. })
    31. io.writeLine("{constrained.optimized.lines[0].cost > unconstrained.optimized.lines[0].cost}")
    Expected outputexit 0
    true
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. true
    Source evidence

    Keep the final line threshold out of nonfinal scoring

    Link
    main.tpzKeep the final line threshold out of nonfinal scoringOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. import std.test
    4. function sample(justification: ts.JustificationPolicy) -> ts.ParagraphResult {
    5. let items: Array<ts.Item> = [
    6. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 4pt, trackingAfter: 0pt }),
    7. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false }),
    8. ts.Item.BoxItem(ts.Box { unitIndex: 1, text: "next", width: 4pt, trackingAfter: 0pt }),
    9. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 2, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    10. ]
    11. let input = ts.Paragraph {
    12. grid: ts.DistanceGrid.MilliPoint(),
    13. items: items,
    14. geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },
    15. justification: justification,
    16. costModel: ts.CostModel.FixedPoint(),
    17. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    18. }
    19. test.assertOk(ts.breakParagraph(input))
    20. }
    21. let ordinary = sample(ts.JustificationPolicy {
    22. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 1,
    23. minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),
    24. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    25. latinSpacing: None(), cjkStretchRatio: 0.0
    26. })
    27. let finalZero = sample(ts.JustificationPolicy {
    28. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 1,
    29. minLineWidthRatioM: 0, minFinalLineWidthRatioM: Some(0),
    30. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    31. latinSpacing: None(), cjkStretchRatio: 0.0
    32. })
    33. io.writeLine("{ordinary.optimized.lines[0].cost == finalZero.optimized.lines[0].cost}")
    Expected outputexit 0
    true
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. true
    Source evidence

    Use explicit glue capacities for the KnuthPlass model

    Link
    main.tpzUse explicit glue capacities for the KnuthPlass modelOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. import std.test
    4. function sample(justification: ts.JustificationPolicy) -> ts.ParagraphResult {
    5. let items: Array<ts.Item> = [
    6. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "word", width: 10pt, trackingAfter: 0pt }),
    7. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    8. ]
    9. let input = ts.Paragraph {
    10. grid: ts.DistanceGrid.MilliPoint(),
    11. items: items,
    12. geometry: ts.LineGeometry { bodyTarget: 10pt, firstTarget: 10pt, dropCapSpan: 0, dropCapInset: 0pt },
    13. justification: justification,
    14. costModel: ts.CostModel.KnuthPlass(),
    15. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    16. }
    17. test.assertOk(ts.breakParagraph(input))
    18. }
    19. let natural = sample(ts.JustificationPolicy {
    20. mode: ts.JustificationMode.Unjustified(), minGapCount: 0,
    21. minLineWidthRatioM: 0, minFinalLineWidthRatioM: None(),
    22. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    23. latinSpacing: None(), cjkStretchRatio: 0.0
    24. })
    25. let scored = sample(ts.JustificationPolicy {
    26. mode: ts.JustificationMode.CjkInterCharacter(), minGapCount: 2,
    27. minLineWidthRatioM: 900, minFinalLineWidthRatioM: Some(1000),
    28. maxAdjustment: 3pt, maxGapAdjustment: 1pt, maxGapRatioR: 0,
    29. latinSpacing: None(), cjkStretchRatio: 0.2
    30. })
    31. io.writeLine("{natural.optimized.totalCost}")
    32. io.writeLine("{scored.optimized.totalCost}")
    33. io.writeLine("{scored.optimized.lines[0].adjustmentRatioR}")
    Expected outputexit 0
    100
    100
    0
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. 100
    2. 100
    3. 0
    Source evidence

    Raise the score when an overwide unit misses a larger minimum

    Link
    main.tpzRaise the score when an overwide unit misses a larger minimumOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. import std.test
    4. function sample(ratio: int) -> ts.ParagraphResult {
    5. let items: Array<ts.Item> = [
    6. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "wide", width: 1.5pt, trackingAfter: 0pt }),
    7. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false }),
    8. ts.Item.BoxItem(ts.Box { unitIndex: 1, text: "end", width: 1pt, trackingAfter: 0pt }),
    9. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 2, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    10. ]
    11. let input = ts.Paragraph {
    12. grid: ts.DistanceGrid.MilliPoint(),
    13. items: items,
    14. geometry: ts.LineGeometry { bodyTarget: 1pt, firstTarget: 1pt, dropCapSpan: 0, dropCapInset: 0pt },
    15. justification: ts.JustificationPolicy {
    16. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 0,
    17. minLineWidthRatioM: ratio, minFinalLineWidthRatioM: None(),
    18. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    19. latinSpacing: None(), cjkStretchRatio: 0.0
    20. },
    21. costModel: ts.CostModel.FixedPoint(),
    22. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    23. }
    24. test.assertOk(ts.breakParagraph(input))
    25. }
    26. let ordinary = sample(0)
    27. let thresholded = sample(2000)
    28. io.writeLine("{thresholded.optimized.lines[0].cost > ordinary.optimized.lines[0].cost}")
    Expected outputexit 0
    true
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. true
    Source evidence

    Include an inserted width in justification without adding gaps

    Link
    main.tpzInclude an inserted width in justification without adding gapsOpen in Playground
    1. import std.typeset as ts
    2. import std.io
    3. import std.test
    4. function sample(textWidth: Length<Pt>, insertionWidth: Length<Pt>) -> ts.ParagraphResult {
    5. let items: Array<ts.Item> = [
    6. ts.Item.BoxItem(ts.Box { unitIndex: 0, text: "a", width: textWidth, trackingAfter: 0pt }),
    7. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 1, width: insertionWidth, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.LatinHyphen(), flagged: false }),
    8. ts.Item.BoxItem(ts.Box { unitIndex: 1, text: "tail", width: 5pt, trackingAfter: 0pt }),
    9. ts.Item.PenaltyItem(ts.Penalty { unitEnd: 2, width: 0pt, rule: ts.BreakRule.Forced(), kind: ts.BreakKind.ForcedEnd(), flagged: false })
    10. ]
    11. let input = ts.Paragraph {
    12. grid: ts.DistanceGrid.MilliPoint(),
    13. items: items,
    14. geometry: ts.LineGeometry { bodyTarget: 5pt, firstTarget: 5pt, dropCapSpan: 0, dropCapInset: 0pt },
    15. justification: ts.JustificationPolicy {
    16. mode: ts.JustificationMode.LatinWordSpace(), minGapCount: 0,
    17. minLineWidthRatioM: 1000, minFinalLineWidthRatioM: None(),
    18. maxAdjustment: 0pt, maxGapAdjustment: 0pt, maxGapRatioR: 0,
    19. latinSpacing: None(), cjkStretchRatio: 0.0
    20. },
    21. costModel: ts.CostModel.FixedPoint(),
    22. knuthPlass: ts.KnuthPlassPolicy { toleranceR: 100000000, linePenalty: 10, fitnessDemerit: 0, flaggedDemerit: 0, finalFlaggedDemerit: 0 }
    23. }
    24. test.assertOk(ts.breakParagraph(input))
    25. }
    26. let inserted = sample(4pt, 1pt)
    27. let measured = sample(5pt, 0pt)
    28. io.writeLine("{inserted.optimized.lines[0].cost == measured.optimized.lines[0].cost}")
    Expected outputexit 0
    true
    
    $ topaz run main.tpz · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. true
    Source evidence

    Menu

    Download