summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-05 21:51:44 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-07-05 21:51:44 +0000
commitafd269413f1982565b16645e6d7578d9c5a7fecf (patch)
tree2fe9341fd376503d383547b064208fd7f4939840
parent05750deb6fbab92a1635b00085f819c96eafb38f (diff)
parentded8747655e4c83065753def16835c7a940ceaab (diff)
downloadpango-afd269413f1982565b16645e6d7578d9c5a7fecf.tar.gz
Merge branch 'line-height' into 'master'
Support line height See merge request GNOME/pango!64
-rw-r--r--docs/layout.pngbin0 -> 27899 bytes
-rw-r--r--docs/layout.svg497
-rw-r--r--docs/meson.build2
-rw-r--r--pango/fonts.c23
-rw-r--r--pango/pango-font-private.h1
-rw-r--r--pango/pango-font.h2
-rw-r--r--pango/pango-layout-private.h1
-rw-r--r--pango/pango-layout.c251
-rw-r--r--pango/pango-layout.h9
-rw-r--r--pango/pangocairo-coretextfont.c1
-rw-r--r--pango/pangocairo-font.c38
-rw-r--r--pango/pangofc-font.c59
-rw-r--r--pango/pangowin32.c1
-rw-r--r--utils/viewer-render.c6
14 files changed, 800 insertions, 91 deletions
diff --git a/docs/layout.png b/docs/layout.png
new file mode 100644
index 00000000..bd28d5be
--- /dev/null
+++ b/docs/layout.png
Binary files differ
diff --git a/docs/layout.svg b/docs/layout.svg
new file mode 100644
index 00000000..09f498b7
--- /dev/null
+++ b/docs/layout.svg
@@ -0,0 +1,497 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg8"
+ sodipodi:docname="layout.svg"
+ inkscape:version="0.92.4 5da689c313, 2019-01-14">
+ <defs
+ id="defs2">
+ <marker
+ inkscape:stockid="TriangleInM"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker14051"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path14049"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(-0.4)" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker7942"
+ refX="0.0"
+ refY="0.0"
+ orient="auto"
+ inkscape:stockid="TriangleOutM">
+ <path
+ transform="scale(0.4)"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ id="path7940" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker7139"
+ refX="0.0"
+ refY="0.0"
+ orient="auto"
+ inkscape:stockid="TriangleOutM">
+ <path
+ transform="scale(0.4)"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ id="path7137" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker7071"
+ refX="0.0"
+ refY="0.0"
+ orient="auto"
+ inkscape:stockid="TriangleOutM">
+ <path
+ transform="scale(0.4)"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ id="path7069" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker6673"
+ refX="0.0"
+ refY="0.0"
+ orient="auto"
+ inkscape:stockid="TriangleInM"
+ inkscape:collect="always">
+ <path
+ transform="scale(-0.4)"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ id="path6671" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutM"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="TriangleOutM"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path1067"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.4)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInM"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="TriangleInM"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path1058"
+ d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(-0.4)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Sstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Sstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path934"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path925"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.8) rotate(180) translate(12.5,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path922"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.8) translate(12.5,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInM"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleInM-0"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1058-6"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="scale(-0.4)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutM"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutM-4"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1067-6"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="scale(0.4)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInM"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleInM-5"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1058-8"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="scale(-0.4)" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleOutM"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutM-6"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1067-2"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="scale(0.4)" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker6673-6"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="TriangleInM">
+ <path
+ inkscape:connector-curvature="0"
+ transform="scale(-0.4)"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ id="path6671-2" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker7139-9"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="TriangleOutM">
+ <path
+ inkscape:connector-curvature="0"
+ transform="scale(0.4)"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ id="path7137-9" />
+ </marker>
+ <marker
+ inkscape:stockid="TriangleInM"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker14051-8"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path14049-1"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="scale(-0.4)" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker7942-3"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="TriangleOutM">
+ <path
+ inkscape:connector-curvature="0"
+ transform="scale(0.4)"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ d="M 5.77,0 -2.88,5 V -5 Z"
+ id="path7940-1" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8284271"
+ inkscape:cx="62.552344"
+ inkscape:cy="945.78705"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:snap-global="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot815"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:85.33333588px;line-height:1.25;font-family:'DejaVu Serif';-inkscape-font-specification:'DejaVu Serif';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
+ transform="scale(0.26458333)"><flowRegion
+ id="flowRegion817"
+ style="font-size:85.33333588px"><rect
+ id="rect819"
+ width="351.42859"
+ height="708.57141"
+ x="211.42857"
+ y="182.51968"
+ style="font-size:85.33333588px" /></flowRegion><flowPara
+ id="flowPara821"
+ style="font-size:96.00000121px">Mg</flowPara></flowRoot> <rect
+ style="fill:none;fill-opacity:1;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none;"
+ id="rect823"
+ width="47.624996"
+ height="24.209377"
+ x="52.255207"
+ y="52.260418" />
+ <rect
+ style="fill:none;fill-opacity:1;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none"
+ id="rect845"
+ width="47.624996"
+ height="24.209377"
+ x="52.255207"
+ y="52.260418" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.13229167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 104.9316,52.260417 c -56.885887,0 -56.885887,0 -56.885887,0 v 0"
+ id="path849"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.13229167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 104.72835,71.043661 c -56.605254,0 -56.605254,0 -56.605254,0 v 0"
+ id="path849-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.13229167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 104.68306,76.469795 c -56.605249,0 -56.605249,0 -56.605249,0 v 0"
+ id="path849-8-0"
+ inkscape:connector-curvature="0" />
+ <flowRoot
+ transform="matrix(0.26458333,0,0,0.26458333,-0.49993439,29.92432)"
+ xml:space="preserve"
+ id="flowRoot815-2"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:85.33333588px;line-height:1.25;font-family:'DejaVu Serif';-inkscape-font-specification:'DejaVu Serif';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"><flowRegion
+ id="flowRegion817-1"
+ style="font-size:85.33333588px"><rect
+ id="rect819-0"
+ width="351.42859"
+ height="708.57141"
+ x="211.42857"
+ y="182.51968"
+ style="font-size:85.33333588px" /></flowRegion><flowPara
+ id="flowPara821-5"
+ style="font-size:96px">Mg</flowPara></flowRoot> <rect
+ style="fill:none;fill-opacity:1;stroke-width:0.26458332;stroke-miterlimit:4;stroke-dasharray:none"
+ id="rect823-1"
+ width="47.624996"
+ height="24.209377"
+ x="51.75528"
+ y="82.184738" />
+ <rect
+ style="fill:none;fill-opacity:1;stroke-width:0.26458332;stroke-miterlimit:4;stroke-dasharray:none"
+ id="rect845-1"
+ width="47.624996"
+ height="24.209377"
+ x="51.75528"
+ y="82.184738" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.13229167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 104.80585,82.184738 c -57.07298,0 -57.07298,0 -57.07298,0 v 0"
+ id="path849-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.13229167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 104.88322,100.82767 c -56.885878,0 -56.885878,0 -56.885878,0 v 0"
+ id="path849-8-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.13229167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 104.83794,106.39412 c -56.979428,0 -56.979428,0 -56.979428,0 v 0"
+ id="path849-8-0-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.25984162px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#TriangleInM);marker-end:url(#TriangleOutM)"
+ d="m 102.52459,70.326803 c -0.0936,-17.322528 -0.0936,-17.322528 -0.0936,-17.322528"
+ id="path920"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.26465496px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker6673);marker-end:url(#marker7139)"
+ d="m 102.45365,72.131518 c -0.13882,3.407593 -0.13882,3.407593 -0.13882,3.407593"
+ id="path10620"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:Cantarell;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+ x="107.29259"
+ y="62.917221"
+ id="text13750"><tspan
+ sodipodi:role="line"
+ id="tspan13748"
+ x="107.29259"
+ y="62.917221"
+ style="stroke-width:0.26458332">Ascent</tspan><tspan
+ sodipodi:role="line"
+ x="107.29259"
+ y="68.208885"
+ style="stroke-width:0.26458332"
+ id="tspan13752" /></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:Cantarell;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+ x="107.10825"
+ y="74.800102"
+ id="text13756"><tspan
+ sodipodi:role="line"
+ id="tspan13754"
+ x="107.10825"
+ y="74.800102"
+ style="stroke-width:0.26458332">Descent</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.26465496px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker6673-6);marker-end:url(#marker7139-9)"
+ d="m 49.428752,77.64513 c -0.13882,3.407594 -0.13882,3.407594 -0.13882,3.407594"
+ id="path10620-0"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:Cantarell;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+ x="28.730095"
+ y="80.757591"
+ id="text14031"><tspan
+ sodipodi:role="line"
+ id="tspan14029"
+ x="28.730095"
+ y="80.757591"
+ style="stroke-width:0.26458332">Spacing</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.26399428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker14051);marker-end:url(#marker7942)"
+ d="M 102.41047,105.39271 C 102.21678,77.415754 102.21678,77.415754 102.21678,77.415754"
+ id="path14041"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.26399428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker14051-8);marker-end:url(#marker7942-3)"
+ d="M 53.385014,99.776343 C 53.19133,71.79943 53.19133,71.79943 53.19133,71.79943"
+ id="path14041-1"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:Cantarell;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
+ x="107.14215"
+ y="92.602859"
+ id="text16168"><tspan
+ sodipodi:role="line"
+ id="tspan16166"
+ x="107.14215"
+ y="92.602859"
+ style="stroke-width:0.26458332">Height</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333333px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332;"
+ x="12.434073"
+ y="62.795258"
+ id="text16172"><tspan
+ sodipodi:role="line"
+ id="tspan16188">Baseline-to-baseline</tspan><tspan
+ sodipodi:role="line"
+ id="tspan16190">distance</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.12913886;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 53.1315,74.164103 c 0,0 -4.818074,0.125651 -7.969503,-0.151187 -2.845534,-0.249967 -5.290399,-0.985067 -7.513672,-1.679659 -4.72719,-1.476863 -7.250826,-3.884947 -7.250826,-3.884947"
+ id="path16192"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssc" />
+ </g>
+</svg>
diff --git a/docs/meson.build b/docs/meson.build
index 9122dc3c..fbfb6072 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -58,7 +58,7 @@ content_files = [
]
html_images = [
- 'layout.gif',
+ 'layout.png',
'rotated-text.png',
]
diff --git a/pango/fonts.c b/pango/fonts.c
index 6a7778d3..f273cd26 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -1793,6 +1793,7 @@ pango_font_get_metrics (PangoFont *font,
metrics->ascent = PANGO_SCALE * PANGO_UNKNOWN_GLYPH_HEIGHT;
metrics->descent = 0;
+ metrics->height = 0;
metrics->approximate_char_width = PANGO_SCALE * PANGO_UNKNOWN_GLYPH_WIDTH;
metrics->approximate_digit_width = PANGO_SCALE * PANGO_UNKNOWN_GLYPH_WIDTH;
metrics->underline_position = -PANGO_SCALE;
@@ -1940,6 +1941,28 @@ pango_font_metrics_get_descent (PangoFontMetrics *metrics)
}
/**
+ * pango_font_metrics_get_height:
+ * @metrics: a #PangoFontMetrics structure
+ *
+ * Gets the line height from a font metrics structure. The
+ * line height is the distance between successive baselines
+ * in wrapped text.
+ *
+ * If the line height is not available, 0 is returned.
+ *
+ * Return value: the height, in Pango units
+ *
+ * Since: 1.44
+ */
+int
+pango_font_metrics_get_height (PangoFontMetrics *metrics)
+{
+ g_return_val_if_fail (metrics != NULL, 0);
+
+ return metrics->height;
+}
+
+/**
* pango_font_metrics_get_approximate_char_width:
* @metrics: a #PangoFontMetrics structure
*
diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h
index 13b05254..44d19dee 100644
--- a/pango/pango-font-private.h
+++ b/pango/pango-font-private.h
@@ -41,6 +41,7 @@ struct _PangoFontMetrics
int ascent;
int descent;
+ int height;
int approximate_char_width;
int approximate_digit_width;
int underline_position;
diff --git a/pango/pango-font.h b/pango/pango-font.h
index 60501216..ceaf9643 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -335,6 +335,8 @@ PANGO_AVAILABLE_IN_ALL
int pango_font_metrics_get_ascent (PangoFontMetrics *metrics) G_GNUC_PURE;
PANGO_AVAILABLE_IN_ALL
int pango_font_metrics_get_descent (PangoFontMetrics *metrics) G_GNUC_PURE;
+PANGO_AVAILABLE_IN_1_44
+int pango_font_metrics_get_height (PangoFontMetrics *metrics) G_GNUC_PURE;
PANGO_AVAILABLE_IN_ALL
int pango_font_metrics_get_approximate_char_width (PangoFontMetrics *metrics) G_GNUC_PURE;
PANGO_AVAILABLE_IN_ALL
diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h
index 4b5327ee..38e2e196 100644
--- a/pango/pango-layout-private.h
+++ b/pango/pango-layout-private.h
@@ -55,6 +55,7 @@ struct _PangoLayout
int height; /* ellipsize width, in device units if positive, number of lines if negative */
int indent; /* amount by which first line should be shorter */
int spacing; /* spacing between lines */
+ float line_spacing; /* factor to apply to line height */
guint justify : 1;
guint alignment : 2;
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index a3850843..1ba614e1 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -49,8 +49,8 @@
* treat the results of a #PangoLayout as a list of lines.
*
* <figure id="parameters">
- * <title>Adjustable parameters for a PangoLayout</title>
- * <graphic fileref="layout.gif" format="GIF"></graphic>
+ * <title>Adjustable parameters (on the left) and font metrics (on the right) for a PangoLayout</title>
+ * <graphic fileref="layout.png" format="PNG"></graphic>
* </figure>
*
* The #PangoLayout structure is opaque, and has no user-visible
@@ -113,6 +113,7 @@ struct _PangoLayoutLinePrivate
} cache_status;
PangoRectangle ink_rect;
PangoRectangle logical_rect;
+ int height;
};
struct _PangoLayoutClass
@@ -189,6 +190,7 @@ pango_layout_init (PangoLayout *layout)
layout->height = -1;
layout->indent = 0;
layout->spacing = 0;
+ layout->line_spacing = 1.0;
layout->alignment = PANGO_ALIGN_LEFT;
layout->justify = FALSE;
@@ -555,8 +557,17 @@ pango_layout_get_indent (PangoLayout *layout)
* @layout: a #PangoLayout.
* @spacing: the amount of spacing
*
- * Sets the amount of spacing in Pango unit between the lines of the
- * layout.
+ * Sets the amount of spacing in Pango unit between
+ * the lines of the layout. When placing lines with
+ * spacing, Pango arranges things so that
+ *
+ * line2.top = line1.bottom + spacing
+ *
+ * Note: Since 1.44, Pango defaults to using the
+ * line height (as determined by the font) for placing
+ * lines. The @spacing set with this function is only
+ * taken into account when the line-height factor is
+ * set to zero with pango_layout_set_line_spacing().
**/
void
pango_layout_set_spacing (PangoLayout *layout,
@@ -587,6 +598,59 @@ pango_layout_get_spacing (PangoLayout *layout)
}
/**
+ * pango_layout_set_line_spacing:
+ * @layout: a #PangoLayout
+ * @factor: the new line spacing factor
+ *
+ * Sets a factor for line spacing.
+ * Typical values are: 0, 1, 1.5, 2.
+ * The default values is 1.
+ *
+ * If @factor is non-zero, lines are placed
+ * so that
+ *
+ * baseline2 = baseline1 + factor * height2
+ *
+ * where height2 is the line height of the
+ * second line (as determined by the font(s)).
+ * In this case, the spacing set with
+ * pango_layout_set_spacing() is ignored.
+ *
+ * If @factor is zero, spacing is applied as
+ * before.
+ *
+ * Since: 1.44
+ */
+void
+pango_layout_set_line_spacing (PangoLayout *layout,
+ float factor)
+{
+ g_return_if_fail (layout != NULL);
+
+ if (layout->line_spacing != factor)
+ {
+ layout->line_spacing = factor;
+ layout_changed (layout);
+ }
+}
+
+/**
+ * pango_layout_get_line_spacing:
+ * @layout: a #PangoLayout
+ *
+ * Gets the value that has been
+ * set with pango_layout_set_line_spacing().
+ *
+ * Since: 1.44
+ */
+float
+pango_layout_get_line_spacing (PangoLayout *layout)
+{
+ g_return_val_if_fail (layout != NULL, 1.0);
+ return layout->line_spacing;
+}
+
+/**
* pango_layout_set_attributes:
* @layout: a #PangoLayout
* @attrs: (allow-none) (transfer none): a #PangoAttrList, can be %NULL
@@ -2481,6 +2545,11 @@ get_x_offset (PangoLayout *layout,
}
static void
+pango_layout_line_get_extents_and_height (PangoLayoutLine *line,
+ PangoRectangle *ink,
+ PangoRectangle *logical,
+ int *height);
+static void
get_line_extents_layout_coords (PangoLayout *layout,
PangoLayoutLine *line,
int layout_width,
@@ -2493,29 +2562,43 @@ get_line_extents_layout_coords (PangoLayout *layout,
/* Line extents in line coords (origin at line baseline) */
PangoRectangle line_ink;
PangoRectangle line_logical;
+ gboolean first_line;
+ int new_baseline;
+ int height;
+
+ if (layout->lines->data == line)
+ first_line = TRUE;
+ else
+ first_line = FALSE;
- pango_layout_line_get_extents (line, line_ink_layout ? &line_ink : NULL,
- &line_logical);
+ pango_layout_line_get_extents_and_height (line, line_ink_layout ? &line_ink : NULL,
+ &line_logical,
+ &height);
get_x_offset (layout, line, layout_width, line_logical.width, &x_offset);
+ if (first_line || !baseline || layout->line_spacing == 0.0)
+ new_baseline = y_offset - line_logical.y;
+ else
+ new_baseline = *baseline + layout->line_spacing * height;
+
/* Convert the line's extents into layout coordinates */
if (line_ink_layout)
{
*line_ink_layout = line_ink;
line_ink_layout->x = line_ink.x + x_offset;
- line_ink_layout->y = y_offset - line_logical.y + line_ink.y;
+ line_ink_layout->y = new_baseline + line_ink.y;
}
if (line_logical_layout)
{
*line_logical_layout = line_logical;
line_logical_layout->x = line_logical.x + x_offset;
- line_logical_layout->y = y_offset;
+ line_logical_layout->y = new_baseline + line_logical.y;
}
if (baseline)
- *baseline = y_offset - line_logical.y;
+ *baseline = new_baseline;
}
/* if non-NULL line_extents returns a list of line extents
@@ -2532,6 +2615,7 @@ pango_layout_get_extents_internal (PangoLayout *layout,
int width;
gboolean need_width = FALSE;
int line_index = 0;
+ int baseline;
g_return_if_fail (layout != NULL);
@@ -2598,6 +2682,7 @@ pango_layout_get_extents_internal (PangoLayout *layout,
*line_extents = g_malloc (sizeof (Extents) * layout->line_count);
}
+ baseline = 0;
line_list = layout->lines;
while (line_list)
{
@@ -2610,8 +2695,6 @@ pango_layout_get_extents_internal (PangoLayout *layout,
/* This block gets the line extents in layout coords */
{
- int baseline;
-
get_line_extents_layout_coords (layout, line,
width, y_offset,
&baseline,
@@ -2683,14 +2766,10 @@ pango_layout_get_extents_internal (PangoLayout *layout,
}
}
- logical_rect->height += line_logical_layout.height;
-
- /* No space after the last line, of course. */
- if (line_list->next != NULL)
- logical_rect->height += layout->spacing;
+ logical_rect->height = line_logical_layout.y + line_logical_layout.height - logical_rect->y;
}
- y_offset += line_logical_layout.height + layout->spacing;
+ y_offset = line_logical_layout.y + line_logical_layout.height + layout->spacing;
line_list = line_list->next;
line_index ++;
}
@@ -4544,12 +4623,14 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line,
}
static void
-pango_layout_run_get_extents (PangoLayoutRun *run,
- PangoRectangle *run_ink,
- PangoRectangle *run_logical)
+pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
+ PangoRectangle *run_ink,
+ PangoRectangle *run_logical,
+ int *height)
{
PangoRectangle logical;
ItemProperties properties;
+ PangoFontMetrics *metrics = NULL;
if (G_UNLIKELY (!run_ink && !run_logical))
return;
@@ -4573,15 +4654,21 @@ pango_layout_run_get_extents (PangoLayoutRun *run,
if (run_ink && (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough))
{
- PangoFontMetrics *metrics = pango_font_get_metrics (run->item->analysis.font,
- run->item->analysis.language);
- int underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
- int underline_position = pango_font_metrics_get_underline_position (metrics);
- int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
- int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);
-
+ int underline_thickness;
+ int underline_position;
+ int strikethrough_thickness;
+ int strikethrough_position;
int new_pos;
+ if (!metrics)
+ metrics = pango_font_get_metrics (run->item->analysis.font,
+ run->item->analysis.language);
+
+ underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
+ underline_position = pango_font_metrics_get_underline_position (metrics);
+ strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
+ strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);
+
/* the underline/strikethrough takes x,width of logical_rect. reflect
* that into ink_rect.
*/
@@ -4625,8 +4712,14 @@ pango_layout_run_get_extents (PangoLayoutRun *run,
g_critical ("unknown underline mode");
break;
}
+ }
- pango_font_metrics_unref (metrics);
+ if (height)
+ {
+ if (!metrics)
+ metrics = pango_font_get_metrics (run->item->analysis.font,
+ run->item->analysis.language);
+ *height = pango_font_metrics_get_height (metrics);
}
if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)
@@ -4648,24 +4741,16 @@ pango_layout_run_get_extents (PangoLayoutRun *run,
if (run_logical)
run_logical->y -= properties.rise;
}
+
+ if (metrics)
+ pango_font_metrics_unref (metrics);
}
-/**
- * pango_layout_line_get_extents:
- * @line: a #PangoLayoutLine
- * @ink_rect: (out) (allow-none): rectangle used to store the extents of
- * the glyph string as drawn, or %NULL
- * @logical_rect: (out) (allow-none):rectangle used to store the logical
- * extents of the glyph string, or %NULL
- *
- * Computes the logical and ink extents of a layout line. See
- * pango_font_get_glyph_extents() for details about the interpretation
- * of the rectangles.
- */
-void
-pango_layout_line_get_extents (PangoLayoutLine *line,
- PangoRectangle *ink_rect,
- PangoRectangle *logical_rect)
+static void
+pango_layout_line_get_extents_and_height (PangoLayoutLine *line,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect,
+ int *height)
{
PangoLayoutLinePrivate *private = (PangoLayoutLinePrivate *)line;
GSList *tmp_list;
@@ -4685,6 +4770,8 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
*ink_rect = private->ink_rect;
if (logical_rect)
*logical_rect = private->logical_rect;
+ if (height)
+ *height = private->height;
return;
}
case NOT_CACHED:
@@ -4694,6 +4781,8 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
ink_rect = &private->ink_rect;
if (!logical_rect)
logical_rect = &private->logical_rect;
+ if (!height)
+ height = &private->height;
break;
}
case LEAKED:
@@ -4718,6 +4807,9 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
logical_rect->height = 0;
}
+ if (height)
+ *height = 0;
+
tmp_list = line->runs;
while (tmp_list)
{
@@ -4725,10 +4817,12 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
int new_pos;
PangoRectangle run_ink;
PangoRectangle run_logical;
+ int run_height;
- pango_layout_run_get_extents (run,
- ink_rect ? &run_ink : NULL,
- &run_logical);
+ pango_layout_run_get_extents_and_height (run,
+ ink_rect ? &run_ink : NULL,
+ &run_logical,
+ height ? &run_height : NULL);
if (ink_rect)
{
@@ -4752,9 +4846,9 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
}
if (logical_rect)
- {
- new_pos = MIN (logical_rect->x, x_pos + run_logical.x);
- logical_rect->width = MAX (logical_rect->x + logical_rect->width,
+ {
+ new_pos = MIN (logical_rect->x, x_pos + run_logical.x);
+ logical_rect->width = MAX (logical_rect->x + logical_rect->width,
x_pos + run_logical.x + run_logical.width) - new_pos;
logical_rect->x = new_pos;
@@ -4762,10 +4856,13 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
logical_rect->height = MAX (logical_rect->y + logical_rect->height,
run_logical.y + run_logical.height) - new_pos;
logical_rect->y = new_pos;
- }
+ }
+
+ if (height)
+ *height = MAX (*height, run_height);
- x_pos += run_logical.width;
- tmp_list = tmp_list->next;
+ x_pos += run_logical.width;
+ tmp_list = tmp_list->next;
}
if (logical_rect && !line->runs)
@@ -4777,10 +4874,49 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
private->ink_rect = *ink_rect;
if (&private->logical_rect != logical_rect)
private->logical_rect = *logical_rect;
+ if (&private->height != height)
+ private->height = *height;
private->cache_status = CACHED;
}
}
+/**
+ * pango_layout_line_get_extents:
+ * @line: a #PangoLayoutLine
+ * @ink_rect: (out) (allow-none): rectangle used to store the extents of
+ * the glyph string as drawn, or %NULL
+ * @logical_rect: (out) (allow-none):rectangle used to store the logical
+ * extents of the glyph string, or %NULL
+ *
+ * Computes the logical and ink extents of a layout line. See
+ * pango_font_get_glyph_extents() for details about the interpretation
+ * of the rectangles.
+ */
+void
+pango_layout_line_get_extents (PangoLayoutLine *line,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ pango_layout_line_get_extents_and_height (line, ink_rect, logical_rect, NULL);
+}
+
+/**
+ * pango_layout_line_get_height:
+ * @line: a #PangoLayoutLine
+ * @height: (out) (allow-none): return location for the line height
+ *
+ * Computes the height of the line, ie the distance between
+ * this and the previous lines baseline.
+ *
+ * Since: 1.44
+ */
+void
+pango_layout_line_get_height (PangoLayoutLine *line,
+ int *height)
+{
+ pango_layout_line_get_extents_and_height (line, NULL, NULL, height);
+}
+
static PangoLayoutLine *
pango_layout_line_new (PangoLayout *layout)
{
@@ -6307,7 +6443,7 @@ pango_layout_iter_get_run_extents (PangoLayoutIter *iter,
if (iter->run)
{
- pango_layout_run_get_extents (iter->run, ink_rect, logical_rect);
+ pango_layout_run_get_extents_and_height (iter->run, ink_rect, logical_rect, NULL);
if (ink_rect)
{
@@ -6372,7 +6508,7 @@ pango_layout_iter_get_line_extents (PangoLayoutIter *iter,
get_line_extents_layout_coords (iter->layout, iter->line,
iter->layout_width,
ext->logical_rect.y,
- NULL,
+ NULL,
ink_rect,
NULL);
}
@@ -6395,7 +6531,10 @@ pango_layout_iter_get_line_extents (PangoLayoutIter *iter,
* The Y positions are in layout coordinates (origin at top left of the
* entire layout).
*
- **/
+ * Note: Since 1.44, Pango uses line heights for placing lines,
+ * and there may be gaps between the ranges returned by this
+ * function.
+ */
void
pango_layout_iter_get_line_yrange (PangoLayoutIter *iter,
int *y0,
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index b095a303..96155715 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -206,6 +206,11 @@ void pango_layout_set_spacing (PangoLayout *la
int spacing);
PANGO_AVAILABLE_IN_ALL
int pango_layout_get_spacing (PangoLayout *layout);
+PANGO_AVAILABLE_IN_1_44
+void pango_layout_set_line_spacing (PangoLayout *layout,
+ float spread);
+PANGO_AVAILABLE_IN_1_44
+float pango_layout_get_line_spacing (PangoLayout *layout);
PANGO_AVAILABLE_IN_ALL
void pango_layout_set_justify (PangoLayout *layout,
gboolean justify);
@@ -352,6 +357,10 @@ PANGO_AVAILABLE_IN_ALL
void pango_layout_line_get_extents (PangoLayoutLine *line,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
+PANGO_AVAILABLE_IN_1_44
+void pango_layout_line_get_height (PangoLayoutLine *line,
+ int *height);
+
PANGO_AVAILABLE_IN_ALL
void pango_layout_line_get_pixel_extents (PangoLayoutLine *layout_line,
PangoRectangle *ink_rect,
diff --git a/pango/pangocairo-coretextfont.c b/pango/pangocairo-coretextfont.c
index 9dc33447..162d08c3 100644
--- a/pango/pangocairo-coretextfont.c
+++ b/pango/pangocairo-coretextfont.c
@@ -139,6 +139,7 @@ pango_cairo_core_text_font_create_base_metrics_for_context (PangoCairoFont *font
metrics->ascent = CTFontGetAscent (ctfont) * PANGO_SCALE;
metrics->descent = CTFontGetDescent (ctfont) * PANGO_SCALE;
+ metrics->height = (CTFontGetAscent (ctfont) + CTFontGetDescent (ctfont) + CTFontGetLeading (ctfont) * PANGO_SCALE;
metrics->underline_position = CTFontGetUnderlinePosition (ctfont) * PANGO_SCALE;
metrics->underline_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index cc2e7bee..7915be6f 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -224,6 +224,7 @@ _pango_cairo_font_get_metrics (PangoFont *font,
PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (font);
PangoCairoFontMetricsInfo *info = NULL; /* Quiet gcc */
GSList *tmp_list;
+ static int in_get_metrics;
const char *sample_str = pango_language_get_sample_string (language);
@@ -293,35 +294,43 @@ _pango_cairo_font_get_metrics (PangoFont *font,
info->metrics->ascent *= xscale;
info->metrics->descent *= xscale;
+ info->metrics->height *= xscale;
info->metrics->underline_position *= xscale;
info->metrics->underline_thickness *= xscale;
info->metrics->strikethrough_position *= xscale;
info->metrics->strikethrough_thickness *= xscale;
}
-
/* Set the matrix on the context so we don't have to adjust the derived
* metrics. */
pango_context_set_matrix (context, &pango_matrix);
- /* Update approximate_*_width now */
- layout = pango_layout_new (context);
- desc = pango_font_describe_with_absolute_size (font);
- pango_layout_set_font_description (layout, desc);
- pango_font_description_free (desc);
+ /* Ugly. We need to prevent recursion when we call into
+ * PangoLayout to determine approximate char width.
+ */
+ if (!in_get_metrics)
+ {
+ in_get_metrics = 1;
- pango_layout_set_text (layout, sample_str, -1);
- pango_layout_get_extents (layout, NULL, &extents);
+ /* Update approximate_*_width now */
+ layout = pango_layout_new (context);
+ desc = pango_font_describe_with_absolute_size (font);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
- sample_str_width = pango_utf8_strwidth (sample_str);
- g_assert (sample_str_width > 0);
- info->metrics->approximate_char_width = extents.width / sample_str_width;
+ pango_layout_set_text (layout, sample_str, -1);
+ pango_layout_get_extents (layout, NULL, &extents);
- pango_layout_set_text (layout, "0123456789", -1);
- info->metrics->approximate_digit_width = max_glyph_width (layout);
+ sample_str_width = pango_utf8_strwidth (sample_str);
+ g_assert (sample_str_width > 0);
+ info->metrics->approximate_char_width = extents.width / sample_str_width;
- g_object_unref (layout);
+ pango_layout_set_text (layout, "0123456789", -1);
+ info->metrics->approximate_digit_width = max_glyph_width (layout);
+ g_object_unref (layout);
+ in_get_metrics = 0;
+ }
/* We may actually reuse ascent/descent we got from cairo here. that's
* in cf_priv->font_extents.
@@ -355,6 +364,7 @@ _pango_cairo_font_get_metrics (PangoFont *font,
g_object_unref (fontmap);
}
+out:
return pango_font_metrics_ref (info->metrics);
}
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 7fd7db0f..79fb07c1 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -390,6 +390,7 @@ get_face_metrics (PangoFcFont *fcfont,
{
metrics->descent = 0;
metrics->ascent = PANGO_SCALE * PANGO_UNKNOWN_GLYPH_HEIGHT;
+ metrics->height = metrics->ascent;
metrics->underline_thickness = PANGO_SCALE;
metrics->underline_position = - PANGO_SCALE;
metrics->strikethrough_thickness = PANGO_SCALE;
@@ -422,24 +423,32 @@ get_face_metrics (PangoFcFont *fcfont,
vector.y = face->size->metrics.ascender;
FT_Vector_Transform (&vector, &ft_matrix);
metrics->ascent = PANGO_UNITS_26_6 (vector.y);
+
+ vector.x = 0;
+ vector.y = face->size->metrics.height;
+ FT_Vector_Transform (&vector, &ft_matrix);
+ metrics->height = PANGO_UNITS_26_6 (vector.y);
}
else if (fcfont->is_hinted ||
(face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
{
metrics->descent = - PANGO_UNITS_26_6 (face->size->metrics.descender);
metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
+ metrics->height = PANGO_UNITS_26_6 (face->size->metrics.height);
}
else
{
- FT_Fixed ascender, descender;
+ FT_Fixed ascender, descender, height;
descender = FT_MulFix (face->descender, face->size->metrics.y_scale);
metrics->descent = - PANGO_UNITS_26_6 (descender);
ascender = FT_MulFix (face->ascender, face->size->metrics.y_scale);
metrics->ascent = PANGO_UNITS_26_6 (ascender);
- }
+ height = FT_MulFix (face->height, face->size->metrics.y_scale);
+ metrics->height = PANGO_UNITS_26_6 (height);
+ }
metrics->underline_thickness = 0;
metrics->underline_position = 0;
@@ -545,6 +554,7 @@ pango_fc_font_get_metrics (PangoFont *font,
PangoFcFont *fcfont = PANGO_FC_FONT (font);
PangoFcMetricsInfo *info = NULL; /* Quiet gcc */
GSList *tmp_list;
+ static int in_get_metrics;
const char *sample_str = pango_language_get_sample_string (language);
@@ -570,6 +580,9 @@ pango_fc_font_get_metrics (PangoFont *font,
info = g_slice_new0 (PangoFcMetricsInfo);
+ /* Note: we need to add info to the list before calling
+ * into PangoLayout below, to prevent recursion
+ */
fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang,
info);
@@ -580,29 +593,35 @@ pango_fc_font_get_metrics (PangoFont *font,
info->metrics = pango_fc_font_create_base_metrics_for_context (fcfont, context);
- { /* Compute derived metrics */
- PangoLayout *layout;
- PangoRectangle extents;
- const char *sample_str = pango_language_get_sample_string (language);
- PangoFontDescription *desc = pango_font_describe_with_absolute_size (font);
- gulong sample_str_width;
+ if (!in_get_metrics)
+ {
+ in_get_metrics = 1;
- layout = pango_layout_new (context);
- pango_layout_set_font_description (layout, desc);
- pango_font_description_free (desc);
+ /* Compute derived metrics */
+ PangoLayout *layout;
+ PangoRectangle extents;
+ const char *sample_str = pango_language_get_sample_string (language);
+ PangoFontDescription *desc = pango_font_describe_with_absolute_size (font);
+ gulong sample_str_width;
- pango_layout_set_text (layout, sample_str, -1);
- pango_layout_get_extents (layout, NULL, &extents);
+ layout = pango_layout_new (context);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
- sample_str_width = pango_utf8_strwidth (sample_str);
- g_assert (sample_str_width > 0);
- info->metrics->approximate_char_width = extents.width / sample_str_width;
+ pango_layout_set_text (layout, sample_str, -1);
+ pango_layout_get_extents (layout, NULL, &extents);
- pango_layout_set_text (layout, "0123456789", -1);
- info->metrics->approximate_digit_width = max_glyph_width (layout);
+ sample_str_width = pango_utf8_strwidth (sample_str);
+ g_assert (sample_str_width > 0);
+ info->metrics->approximate_char_width = extents.width / sample_str_width;
- g_object_unref (layout);
- }
+ pango_layout_set_text (layout, "0123456789", -1);
+ info->metrics->approximate_digit_width = max_glyph_width (layout);
+
+ g_object_unref (layout);
+
+ in_get_metrics = 0;
+ }
g_object_unref (context);
g_object_unref (fontmap);
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index 630898e0..6f60a70c 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -575,6 +575,7 @@ pango_win32_font_get_metrics (PangoFont *font,
metrics->ascent = tm.tmAscent * PANGO_SCALE;
metrics->descent = tm.tmDescent * PANGO_SCALE;
+ metrics->height = (tm.tmHeight + tm.tmInternalLeading + tm.tmExternalLeading) * PANGO_SCALE;
metrics->approximate_char_width = tm.tmAveCharWidth * PANGO_SCALE;
coverage = pango_win32_font_get_coverage (font, language);
diff --git a/utils/viewer-render.c b/utils/viewer-render.c
index 51ba00fb..5a556cd8 100644
--- a/utils/viewer-render.c
+++ b/utils/viewer-render.c
@@ -52,6 +52,7 @@ int opt_width = -1;
int opt_height = -1;
int opt_indent = 0;
int opt_spacing = 0;
+double opt_line_spacing = 0.0;
gboolean opt_justify = 0;
int opt_runs = 1;
PangoAlignment opt_align = PANGO_ALIGN_LEFT;
@@ -126,6 +127,9 @@ make_layout(PangoContext *context,
if (opt_spacing != 0)
pango_layout_set_spacing (layout, (opt_spacing * opt_dpi * PANGO_SCALE + 36) / 72);
+ if (opt_line_spacing != 0.0)
+ pango_layout_set_line_spacing (layout, (float)opt_line_spacing);
+
align = opt_align;
if (align != PANGO_ALIGN_CENTER &&
pango_context_get_base_dir (context) != PANGO_DIRECTION_LTR) {
@@ -710,6 +714,8 @@ parse_options (int argc, char *argv[])
"Width in points to indent paragraphs", "points"},
{"spacing", 0, 0, G_OPTION_ARG_INT, &opt_spacing,
"Spacing in points between lines", "points"},
+ {"line-spacing", 0, 0, G_OPTION_ARG_DOUBLE, &opt_line_spacing,
+ "Spread factor for line height", "factor"},
{"justify", 0, 0, G_OPTION_ARG_NONE, &opt_justify,
"Align paragraph lines to be justified", NULL},
{"language", 0, 0, G_OPTION_ARG_STRING, &opt_language,