+2008-03-24 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Maciej.
+
+ - test case and new results for "SVGTextElement.getStartPositionOfChar does not correctly account for multichar glyphs"
+ http://bugs.webkit.org/show_bug.cgi?id=18046
+
+ * svg/text/multichar-glyph.svg: Added. New test case for both rendering and getStartPositionOfChar
+ access of multichar glyphs.
+ * platform/mac/svg/text/multichar-glyph-expected.txt: Added.
+
+ The following test results changed, all appear to be improvements.
+
+ * platform/mac/svg/W3C-SVG-1.1/fonts-glyph-04-t-expected.txt:
+ * platform/mac/svg/W3C-SVG-1.1/text-altglyph-01-b-expected.txt:
+ * platform/mac/svg/W3C-SVG-1.1/text-text-06-t-expected.txt:
+ * platform/mac/svg/text/text-altglyph-01-b-expected.txt:
+ * platform/mac/svg/text/text-text-06-t-expected.txt:
+
2008-03-25 Beth Dakin <bdakin@apple.com>
Reviewed by Oliver.
RenderView at (0,0) size 480x360
layer at (0,0) size 480x360
RenderSVGRoot {svg} at (0.50,0.50) size 479x359
- RenderSVGContainer {g} at (100,60) size 64x150
+ RenderSVGContainer {g} at (100,60) size 25x150
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
- RenderSVGText {text} at (100,100) size 64x50 contains 1 chunk(s)
- RenderSVGInlineText {#text} at (0,-40) size 64x50
+ RenderSVGText {text} at (100,100) size 25x50 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-40) size 25x50
chunk 1 text run 1 at (100.00,100.00) startOffset 0 endOffset 3 width 25.00: "ffl"
- RenderSVGText {text} at (100,200) size 64x50 contains 1 chunk(s)
- RenderSVGInlineText {#text} at (0,-40) size 64x50
+ RenderSVGText {text} at (100,200) size 25x50 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-40) size 25x50
chunk 1 text run 1 at (100.00,200.00) startOffset 0 endOffset 3 width 25.00: "ffl"
RenderSVGText {text} at (10,340) size 284x46 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 284x46
RenderView at (0,0) size 480x360
layer at (0,0) size 480x360
RenderSVGRoot {svg} at (0.50,0.50) size 479x359
- RenderSVGContainer {g} at (5,14) size 463.67x271.67
+ RenderSVGContainer {g} at (5,14) size 463x271.67
RenderSVGText {text} at (5,50) size 403x44 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 403x44
chunk 1 text run 1 at (5.00,50.00) startOffset 0 endOffset 26 width 403.00: "Test 'altGlyph' facilities"
RenderSVGInlineText {#text} at (0,-27) size 463x33
chunk 1 text run 1 at (5.00,90.00) startOffset 0 endOffset 32 width 463.00: "and many-to-many chars to glyphs"
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
- RenderSVGContainer {g} at (49.33,137.33) size 419.33x148.33
+ RenderSVGContainer {g} at (49.33,137.33) size 389.33x148.33
RenderSVGText {text} at (140,190) size 188x67 contains 1 chunk(s)
RenderSVGTSpan {altGlyph} at (0,0) size 38x67
RenderSVGInlineText {#text} at (0,-52) size 38x67
chunk 1 text run 2 at (87.50,270.00) startOffset 0 endOffset 1 width 37.50: "A"
RenderSVGInlineText {#text} at (75,-52) size 38x67
chunk 1 text run 3 at (125.00,270.00) startOffset 0 endOffset 1 width 37.50: "D"
- RenderSVGText {text} at (280,270) size 188x67 contains 1 chunk(s)
- RenderSVGInlineText {#text} at (0,-52) size 188x67
+ RenderSVGText {text} at (280,270) size 158x67 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-52) size 158x67
chunk 1 text run 1 at (280.00,270.00) startOffset 0 endOffset 5 width 157.50: "SASSY"
RenderSVGText {text} at (10,340) size 264x46 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 264x46
RenderView at (0,0) size 480x360
layer at (0,0) size 480x360
RenderSVGRoot {svg} at (0.50,0.50) size 479x359
- RenderSVGContainer {g} at (30,55) size 278x209
+ RenderSVGContainer {g} at (30,55) size 274x209
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
RenderSVGContainer {g} at (-4,-15) size 8x19
RenderPath {line} at (-0.50,-15) size 1x15 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (-4,-4) size 8x8 [fill={[type=SOLID] [color=#000000]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGContainer {g} at (30,55) size 278x209 [transform={m=((1.00,0.00)(0.00,1.00)) t=(20.00,30.00)}]
+ RenderSVGContainer {g} at (30,55) size 274x209 [transform={m=((1.00,0.00)(0.00,1.00)) t=(20.00,30.00)}]
RenderSVGContainer {g} at (30,59) size 71x154 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,40.00)}]
RenderSVGText {text} at (0,0) size 62x14 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-11) size 62x14
RenderSVGText {text} at (0,140) size 71x14 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-11) size 71x14
chunk 1 text run 1 at (0.00,140.00) startOffset 0 endOffset 15 width 71.00: "x/y positioning"
- RenderSVGContainer {g} at (126,55) size 182x19 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,40.00)}]
+ RenderSVGContainer {g} at (126,55) size 178x19 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,40.00)}]
RenderSVGContainer {use} at (126,55) size 8x19
RenderSVGContainer {g} at (126,55) size 8x19 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,0.00)}]
RenderSVGContainer {g} at (126,55) size 8x19
RenderSVGContainer {g} at (246,55) size 8x19
RenderPath {line} at (249.50,55) size 1x15 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#8888FF]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (246,66) size 8x8 [fill={[type=SOLID] [color=#8888FF]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGText {text} at (10,0) size 178x10 contains 6 chunk(s)
- RenderSVGInlineText {#text} at (0,-8) size 178x10
- chunk 1 text run 1 at (10.00,0.00) startOffset 0 endOffset 1 width 8.00: "f"
- chunk 2 text run 1 at (180.00,0.00) startOffset 1 endOffset 2 width 8.00: "i"
- chunk 3 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
- chunk 4 text run 1 at (70.00,0.00) startOffset 3 endOffset 4 width 15.00: "2"
- chunk 5 text run 1 at (100.00,0.00) startOffset 4 endOffset 5 width 15.00: "3"
- chunk 6 text run 1 at (130.00,0.00) startOffset 5 endOffset 6 width 15.00: "4"
- RenderSVGContainer {g} at (116,85) size 80x79 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,80.00)}]
+ RenderSVGText {text} at (10,0) size 135x10 contains 5 chunk(s)
+ RenderSVGInlineText {#text} at (0,-8) size 135x10
+ chunk 1 text run 1 at (10.00,0.00) startOffset 0 endOffset 2 width 15.00: "fi"
+ chunk 2 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
+ chunk 3 text run 1 at (70.00,0.00) startOffset 3 endOffset 4 width 15.00: "2"
+ chunk 4 text run 1 at (100.00,0.00) startOffset 4 endOffset 5 width 15.00: "3"
+ chunk 5 text run 1 at (130.00,0.00) startOffset 5 endOffset 6 width 15.00: "4"
+ RenderSVGContainer {g} at (116,85) size 79x79 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,80.00)}]
RenderSVGContainer {use} at (116,85) size 8x19
RenderSVGContainer {g} at (116,85) size 8x19 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,-10.00)}]
RenderSVGContainer {g} at (116,85) size 8x19
RenderSVGContainer {g} at (176,125) size 8x19
RenderPath {line} at (179.50,125) size 1x15 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#8888FF]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (176,136) size 8x8 [fill={[type=SOLID] [color=#8888FF]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGText {text} at (0,-10) size 76x70 contains 1 chunk(s)
- RenderSVGInlineText {#text} at (0,-8) size 76x70
+ RenderSVGText {text} at (0,-10) size 75x50 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-8) size 75x50
chunk 1 text run 1 at (0.00,-10.00) startOffset 0 endOffset 6 width 75.00: "fi1234"
- RenderSVGContainer {g} at (126,185) size 182x79 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,180.00)}]
+ RenderSVGContainer {g} at (126,185) size 178x79 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,180.00)}]
RenderSVGContainer {use} at (126,185) size 8x19
RenderSVGContainer {g} at (126,185) size 8x19 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,-10.00)}]
RenderSVGContainer {g} at (126,185) size 8x19
RenderSVGContainer {g} at (246,225) size 8x19
RenderPath {line} at (249.50,225) size 1x15 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#8888FF]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (246,236) size 8x8 [fill={[type=SOLID] [color=#8888FF]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGText {text} at (10,-10) size 178x70 contains 6 chunk(s)
- RenderSVGInlineText {#text} at (0,-8) size 178x70
- chunk 1 text run 1 at (10.00,-10.00) startOffset 0 endOffset 1 width 8.00: "f"
- chunk 2 text run 1 at (180.00,50.00) startOffset 1 endOffset 2 width 8.00: "i"
- chunk 3 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
- chunk 4 text run 1 at (70.00,10.00) startOffset 3 endOffset 4 width 15.00: "2"
- chunk 5 text run 1 at (100.00,20.00) startOffset 4 endOffset 5 width 15.00: "3"
- chunk 6 text run 1 at (130.00,30.00) startOffset 5 endOffset 6 width 15.00: "4"
+ RenderSVGText {text} at (10,-10) size 135x50 contains 5 chunk(s)
+ RenderSVGInlineText {#text} at (0,-8) size 135x50
+ chunk 1 text run 1 at (10.00,-10.00) startOffset 0 endOffset 2 width 15.00: "fi"
+ chunk 2 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
+ chunk 3 text run 1 at (70.00,10.00) startOffset 3 endOffset 4 width 15.00: "2"
+ chunk 4 text run 1 at (100.00,20.00) startOffset 4 endOffset 5 width 15.00: "3"
+ chunk 5 text run 1 at (130.00,30.00) startOffset 5 endOffset 6 width 15.00: "4"
RenderSVGText {text} at (10,340) size 264x46 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 264x46
chunk 1 text run 1 at (10.00,340.00) startOffset 0 endOffset 16 width 264.00: "$Revision: 1.9 $"
--- /dev/null
+layer at (0,0) size 808x585
+ RenderView at (0,0) size 800x585
+layer at (0,0) size 808x585
+ RenderBlock {html} at (0,0) size 800x585
+ RenderBody {body} at (8,16) size 784x415
+ RenderBlock {p} at (0,0) size 784x36
+ RenderText {#text} at (0,0) size 783x36
+ text run at (0,0) width 783: "The left edges of the black boxes below should line up with the left edges of their containing red or green boxes. In addition,"
+ text run at (0,18) width 227: "all the assertions below should pass."
+ RenderBlock {div} at (0,52) size 800x200
+ RenderSVGRoot {svg} at (8,-2) size 450x240
+ RenderPath {rect} at (8,78) size 70x160 [fill={[type=SOLID] [color=#FF0000]}] [data="M0.00,10.00L70.00,10.00L70.00,170.00L0.00,170.00"]
+ RenderPath {rect} at (78,78) size 100x150 [fill={[type=SOLID] [color=#008000]}] [data="M70.00,10.00L170.00,10.00L170.00,160.00L70.00,160.00"]
+ RenderPath {rect} at (178,78) size 70x140 [fill={[type=SOLID] [color=#FF0000]}] [data="M170.00,10.00L240.00,10.00L240.00,150.00L170.00,150.00"]
+ RenderPath {rect} at (248,78) size 70x130 [fill={[type=SOLID] [color=#008000]}] [data="M240.00,10.00L310.00,10.00L310.00,140.00L240.00,140.00"]
+ RenderPath {rect} at (318,78) size 80x120 [fill={[type=SOLID] [color=#FF0000]}] [data="M310.00,10.00L390.00,10.00L390.00,130.00L310.00,130.00"]
+ RenderPath {rect} at (398,78) size 60x110 [fill={[type=SOLID] [color=#008000]}] [data="M390.00,10.00L450.00,10.00L450.00,120.00L390.00,120.00"]
+ RenderSVGText {text} at (0,10) size 450x100 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-80) size 450x100
+ chunk 1 text run 1 at (0.00,10.00) startOffset 0 endOffset 10 width 450.00: "GGDGGBBBDB"
+ RenderText {#text} at (0,0) size 0x0
+ RenderBlock {pre} at (0,265) size 784x150
+ RenderInline {span} at (0,0) size 312x15
+ RenderInline {span} at (0,0) size 312x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,0) size 32x15
+ text run at (0,0) width 32: "PASS"
+ RenderText {#text} at (32,0) size 280x15
+ text run at (32,0) width 280: " t.getStartPositionOfChar(0).x is 0"
+ RenderBR {br} at (312,0) size 0x15
+ RenderInline {span} at (0,0) size 312x15
+ RenderInline {span} at (0,0) size 312x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,15) size 32x15
+ text run at (0,15) width 32: "PASS"
+ RenderText {#text} at (32,15) size 280x15
+ text run at (32,15) width 280: " t.getStartPositionOfChar(1).x is 0"
+ RenderBR {br} at (312,15) size 0x15
+ RenderInline {span} at (0,0) size 352x15
+ RenderInline {span} at (0,0) size 352x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,30) size 32x15
+ text run at (0,30) width 32: "PASS"
+ RenderText {#text} at (32,30) size 320x15
+ text run at (32,30) width 320: " t.getStartPositionOfChar(2).x is 0 + 70"
+ RenderBR {br} at (352,30) size 0x15
+ RenderInline {span} at (0,0) size 400x15
+ RenderInline {span} at (0,0) size 400x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,45) size 32x15
+ text run at (0,45) width 32: "PASS"
+ RenderText {#text} at (32,45) size 368x15
+ text run at (32,45) width 368: " t.getStartPositionOfChar(3).x is 0 + 70 + 100"
+ RenderBR {br} at (400,45) size 0x15
+ RenderInline {span} at (0,0) size 400x15
+ RenderInline {span} at (0,0) size 400x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,60) size 32x15
+ text run at (0,60) width 32: "PASS"
+ RenderText {#text} at (32,60) size 368x15
+ text run at (32,60) width 368: " t.getStartPositionOfChar(4).x is 0 + 70 + 100"
+ RenderBR {br} at (400,60) size 0x15
+ RenderInline {span} at (0,0) size 440x15
+ RenderInline {span} at (0,0) size 440x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,75) size 32x15
+ text run at (0,75) width 32: "PASS"
+ RenderText {#text} at (32,75) size 408x15
+ text run at (32,75) width 408: " t.getStartPositionOfChar(5).x is 0 + 70 + 100 + 70"
+ RenderBR {br} at (440,75) size 0x15
+ RenderInline {span} at (0,0) size 440x15
+ RenderInline {span} at (0,0) size 440x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,90) size 32x15
+ text run at (0,90) width 32: "PASS"
+ RenderText {#text} at (32,90) size 408x15
+ text run at (32,90) width 408: " t.getStartPositionOfChar(6).x is 0 + 70 + 100 + 70"
+ RenderBR {br} at (440,90) size 0x15
+ RenderInline {span} at (0,0) size 480x15
+ RenderInline {span} at (0,0) size 480x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,105) size 32x15
+ text run at (0,105) width 32: "PASS"
+ RenderText {#text} at (32,105) size 448x15
+ text run at (32,105) width 448: " t.getStartPositionOfChar(7).x is 0 + 70 + 100 + 70 + 70"
+ RenderBR {br} at (480,105) size 0x15
+ RenderInline {span} at (0,0) size 480x15
+ RenderInline {span} at (0,0) size 480x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,120) size 32x15
+ text run at (0,120) width 32: "PASS"
+ RenderText {#text} at (32,120) size 448x15
+ text run at (32,120) width 448: " t.getStartPositionOfChar(8).x is 0 + 70 + 100 + 70 + 70"
+ RenderBR {br} at (480,120) size 0x15
+ RenderInline {span} at (0,0) size 520x15
+ RenderInline {span} at (0,0) size 520x15
+ RenderInline {span} at (0,0) size 32x15
+ RenderText {#text} at (0,135) size 32x15
+ text run at (0,135) width 32: "PASS"
+ RenderText {#text} at (32,135) size 488x15
+ text run at (32,135) width 488: " t.getStartPositionOfChar(9).x is 0 + 70 + 100 + 70 + 70 + 80"
+ RenderBR {br} at (520,135) size 0x15
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
RenderSVGRoot {svg} at (0.83,0.83) size 798.33x598.33
- RenderSVGContainer {g} at (8.33,23.33) size 772.78x452.78
+ RenderSVGContainer {g} at (8.33,23.33) size 771.67x452.78
RenderSVGText {text} at (5,50) size 403x44 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 403x44
chunk 1 text run 1 at (5.00,50.00) startOffset 0 endOffset 26 width 403.00: "Test 'altGlyph' facilities"
RenderSVGInlineText {#text} at (0,-27) size 463x33
chunk 1 text run 1 at (5.00,90.00) startOffset 0 endOffset 32 width 463.00: "and many-to-many chars to glyphs"
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
- RenderSVGContainer {g} at (82.22,228.89) size 698.89x247.22
+ RenderSVGContainer {g} at (82.22,228.89) size 648.89x247.22
RenderSVGText {text} at (140,190) size 188x67 contains 1 chunk(s)
RenderSVGTSpan {altGlyph} at (0,0) size 38x67
RenderSVGInlineText {#text} at (0,-52) size 38x67
chunk 1 text run 2 at (87.50,270.00) startOffset 0 endOffset 1 width 37.50: "A"
RenderSVGInlineText {#text} at (75,-52) size 38x67
chunk 1 text run 3 at (125.00,270.00) startOffset 0 endOffset 1 width 37.50: "D"
- RenderSVGText {text} at (280,270) size 188x67 contains 1 chunk(s)
- RenderSVGInlineText {#text} at (0,-52) size 188x67
+ RenderSVGText {text} at (280,270) size 158x67 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-52) size 158x67
chunk 1 text run 1 at (280.00,270.00) startOffset 0 endOffset 5 width 157.50: "SASSY"
RenderSVGText {text} at (10,340) size 264x46 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 264x46
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
RenderSVGRoot {svg} at (0.83,0.83) size 798.33x598.33
- RenderSVGContainer {g} at (50,91.67) size 463.33x348.33
+ RenderSVGContainer {g} at (50,91.67) size 456.67x348.33
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
RenderSVGContainer {g} at (-4,-15) size 8x19
RenderPath {line} at (-0.50,-15) size 1x15 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (-4,-4) size 8x8 [fill={[type=SOLID] [color=#000000]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGContainer {g} at (50,91.67) size 463.33x348.33 [transform={m=((1.00,0.00)(0.00,1.00)) t=(20.00,30.00)}]
+ RenderSVGContainer {g} at (50,91.67) size 456.67x348.33 [transform={m=((1.00,0.00)(0.00,1.00)) t=(20.00,30.00)}]
RenderSVGContainer {g} at (50,98.33) size 118.33x256.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,40.00)}]
RenderSVGText {text} at (0,0) size 62x14 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-11) size 62x14
RenderSVGText {text} at (0,140) size 71x14 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-11) size 71x14
chunk 1 text run 1 at (0.00,140.00) startOffset 0 endOffset 15 width 71.00: "x/y positioning"
- RenderSVGContainer {g} at (210,91.67) size 303.33x31.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,40.00)}]
+ RenderSVGContainer {g} at (210,91.67) size 296.67x31.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,40.00)}]
RenderSVGContainer {use} at (210,91.67) size 13.33x31.67
RenderSVGContainer {g} at (210,91.67) size 13.33x31.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,0.00)}]
RenderSVGContainer {g} at (210,91.67) size 13.33x31.67
RenderSVGContainer {g} at (410,91.67) size 13.33x31.67
RenderPath {line} at (415.83,91.67) size 1.67x25 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#8888FF]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (410,110) size 13.33x13.33 [fill={[type=SOLID] [color=#8888FF]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGText {text} at (10,0) size 178x10 contains 6 chunk(s)
- RenderSVGInlineText {#text} at (0,-8) size 178x10
- chunk 1 text run 1 at (10.00,0.00) startOffset 0 endOffset 1 width 8.00: "f"
- chunk 2 text run 1 at (180.00,0.00) startOffset 1 endOffset 2 width 8.00: "i"
- chunk 3 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
- chunk 4 text run 1 at (70.00,0.00) startOffset 3 endOffset 4 width 15.00: "2"
- chunk 5 text run 1 at (100.00,0.00) startOffset 4 endOffset 5 width 15.00: "3"
- chunk 6 text run 1 at (130.00,0.00) startOffset 5 endOffset 6 width 15.00: "4"
- RenderSVGContainer {g} at (193.33,141.67) size 133.33x131.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,80.00)}]
+ RenderSVGText {text} at (10,0) size 135x10 contains 5 chunk(s)
+ RenderSVGInlineText {#text} at (0,-8) size 135x10
+ chunk 1 text run 1 at (10.00,0.00) startOffset 0 endOffset 2 width 15.00: "fi"
+ chunk 2 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
+ chunk 3 text run 1 at (70.00,0.00) startOffset 3 endOffset 4 width 15.00: "2"
+ chunk 4 text run 1 at (100.00,0.00) startOffset 4 endOffset 5 width 15.00: "3"
+ chunk 5 text run 1 at (130.00,0.00) startOffset 5 endOffset 6 width 15.00: "4"
+ RenderSVGContainer {g} at (193.33,141.67) size 131.67x131.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,80.00)}]
RenderSVGContainer {use} at (193.33,141.67) size 13.33x31.67
RenderSVGContainer {g} at (193.33,141.67) size 13.33x31.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,-10.00)}]
RenderSVGContainer {g} at (193.33,141.67) size 13.33x31.67
RenderSVGContainer {g} at (293.33,208.33) size 13.33x31.67
RenderPath {line} at (299.17,208.33) size 1.67x25 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#8888FF]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (293.33,226.67) size 13.33x13.33 [fill={[type=SOLID] [color=#8888FF]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGText {text} at (0,-10) size 76x70 contains 1 chunk(s)
- RenderSVGInlineText {#text} at (0,-8) size 76x70
+ RenderSVGText {text} at (0,-10) size 75x50 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,-8) size 75x50
chunk 1 text run 1 at (0.00,-10.00) startOffset 0 endOffset 6 width 75.00: "fi1234"
- RenderSVGContainer {g} at (210,308.33) size 303.33x131.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,180.00)}]
+ RenderSVGContainer {g} at (210,308.33) size 296.67x131.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,180.00)}]
RenderSVGContainer {use} at (210,308.33) size 13.33x31.67
RenderSVGContainer {g} at (210,308.33) size 13.33x31.67 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,-10.00)}]
RenderSVGContainer {g} at (210,308.33) size 13.33x31.67
RenderSVGContainer {g} at (410,375) size 13.33x31.67
RenderPath {line} at (415.83,375) size 1.67x25 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#8888FF]}] [data="M0.00,0.00L0.00,-15.00"]
RenderPath {rect} at (410,393.33) size 13.33x13.33 [fill={[type=SOLID] [color=#8888FF]}] [data="M-4.00,-4.00L4.00,-4.00L4.00,4.00L-4.00,4.00"]
- RenderSVGText {text} at (10,-10) size 178x70 contains 6 chunk(s)
- RenderSVGInlineText {#text} at (0,-8) size 178x70
- chunk 1 text run 1 at (10.00,-10.00) startOffset 0 endOffset 1 width 8.00: "f"
- chunk 2 text run 1 at (180.00,50.00) startOffset 1 endOffset 2 width 8.00: "i"
- chunk 3 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
- chunk 4 text run 1 at (70.00,10.00) startOffset 3 endOffset 4 width 15.00: "2"
- chunk 5 text run 1 at (100.00,20.00) startOffset 4 endOffset 5 width 15.00: "3"
- chunk 6 text run 1 at (130.00,30.00) startOffset 5 endOffset 6 width 15.00: "4"
+ RenderSVGText {text} at (10,-10) size 135x50 contains 5 chunk(s)
+ RenderSVGInlineText {#text} at (0,-8) size 135x50
+ chunk 1 text run 1 at (10.00,-10.00) startOffset 0 endOffset 2 width 15.00: "fi"
+ chunk 2 text run 1 at (40.00,0.00) startOffset 2 endOffset 3 width 15.00: "1"
+ chunk 3 text run 1 at (70.00,10.00) startOffset 3 endOffset 4 width 15.00: "2"
+ chunk 4 text run 1 at (100.00,20.00) startOffset 4 endOffset 5 width 15.00: "3"
+ chunk 5 text run 1 at (130.00,30.00) startOffset 5 endOffset 6 width 15.00: "4"
RenderSVGText {text} at (10,340) size 264x46 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,-36) size 264x46
chunk 1 text run 1 at (10.00,340.00) startOffset 0 endOffset 16 width 264.00: "$Revision: 1.9 $"
--- /dev/null
+<html xmlns="http://www.w3.org/1999/xhtml" style="width: 100%; height: 100%;">
+<body>
+<p>The left edges of the black boxes below should line up with the
+left edges of their containing red or green boxes. In addition, all
+the assertions below should pass.</p>
+
+<div style="width: 800px; height: 200px;">
+<svg xmlns="http://www.w3.org/2000/svg">
+<font>
+<font-face font-family="xyzzy" units-per-em="100" ascent="100" descent="500">
+</font-face>
+<glyph unicode="BD" d="M0,0 h40 v-80 h-40 z" horiz-adv-x="80">
+</glyph>
+<glyph unicode="GG" d="M0,0 h20 v-60 h-20 z" horiz-adv-x="70">
+</glyph>
+<glyph unicode="BB" d="M0,0 h20 v-70 h-20 z" horiz-adv-x="70">
+</glyph>
+<glyph unicode="B" d="M0,0 h30 v-40 h-30 z" horiz-adv-x="60">
+</glyph>
+<glyph unicode="D" d="M0,0 h30 v-40 h-30 z" horiz-adv-x="100">
+</glyph>
+<glyph unicode="G" d="M0,0 h30 v-40 h-30 z" horiz-adv-x="60">
+</glyph>
+</font>
+<rect x="0" y="10" width="70" height="160" fill="red"/>
+<rect x="70" y="10" width="100" height="150" fill="green"/>
+<rect x="170" y="10" width="70" height="140" fill="red"/>
+<rect x="240" y="10" width="70" height="130" fill="green"/>
+<rect x="310" y="10" width="80" height="120" fill="red"/>
+<rect x="390" y="10" width="60" height="110" fill="green"/>
+<text id="foo" y="10" font-family="xyzzy" font-size="100px" letter-spacing="0px" word-spacing="0px">GGDGGBBBDB</text>
+</svg>
+</div>
+<pre id="console" />
+<script>
+<![CDATA[
+
+function debug(msg)
+{
+ var span = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
+ document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace
+ span.innerHTML = msg + '<br />';
+}
+
+function escapeHTML(text)
+{
+ return text.replace(/&/g, "&").replace(/</g, "<");
+}
+
+function testPassed(msg)
+{
+ debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function testFailed(msg)
+{
+ debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function areArraysEqual(_a, _b)
+{
+ if (_a.length !== _b.length)
+ return false;
+ for (var i = 0; i < _a.length; i++)
+ if (_a[i] !== _b[i])
+ return false;
+ return true;
+}
+
+function isResultCorrect(_actual, _expected)
+{
+ if (_actual === _expected)
+ return true;
+ if (typeof(_expected) == "number" && isNaN(_expected))
+ return typeof(_actual) == "number" && isNaN(_actual);
+ if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([]))
+ return areArraysEqual(_actual, _expected);
+ return false;
+}
+
+function shouldBe(_a, _b)
+{
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBe() expects string arguments");
+ var exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ exception = e;
+ }
+ var _bv = eval(_b);
+
+ if (exception)
+ testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
+ else if (isResultCorrect(_av, _bv))
+ testPassed(_a + " is " + _b);
+ else if (typeof(_av) == typeof(_bv))
+ testFailed(_a + " should be " + _bv + ". Was " + _av + ".");
+ else
+ testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
+}
+
+var t = document.getElementById("foo");
+shouldBe("t.getStartPositionOfChar(0).x", '0');
+shouldBe("t.getStartPositionOfChar(1).x", '0');
+shouldBe("t.getStartPositionOfChar(2).x", '0 + 70');
+shouldBe("t.getStartPositionOfChar(3).x", '0 + 70 + 100');
+shouldBe("t.getStartPositionOfChar(4).x", '0 + 70 + 100');
+shouldBe("t.getStartPositionOfChar(5).x", '0 + 70 + 100 + 70');
+shouldBe("t.getStartPositionOfChar(6).x", '0 + 70 + 100 + 70');
+shouldBe("t.getStartPositionOfChar(7).x", '0 + 70 + 100 + 70 + 70');
+shouldBe("t.getStartPositionOfChar(8).x", '0 + 70 + 100 + 70 + 70');
+shouldBe("t.getStartPositionOfChar(9).x", '0 + 70 + 100 + 70 + 70 + 80');
+]]>
+</script>
+</body>
+</html>
+
+2008-03-24 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Maciej.
+
+ - fixed "SVGTextElement.getStartPositionOfChar does not correctly account for multichar glyphs"
+ http://bugs.webkit.org/show_bug.cgi?id=18046
+
+ * platform/graphics/Font.cpp:
+ (WebCore::Font::floatWidth): Allow expressing a run that has extra "context" characters beyond the end,
+ and reporting of how many characters were actually consumed, to support multichar glyphs in SVG fonts.
+ * platform/graphics/Font.h:
+ * rendering/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::calculateGlyphWidth): Pass along extra chars in argument and chars consumed out
+ argument.
+ (WebCore::SVGInlineTextBox::calculateGlyphHeight): Pass along extra chars in argument.
+ (WebCore::SVGInlineTextBox::calculateGlyphBoundaries): Add boilerplate; may not handle multichar glyphs
+ right but I don't know what effects this would have.
+ * rendering/SVGInlineTextBox.h:
+ * rendering/SVGRootInlineBox.cpp:
+ (WebCore::cummulatedWidthOrHeightOfTextChunk): Add boilerplate; may not handle multichar glyphs right
+ but again I am not sure what effect this would have.
+ (WebCore::SVGRootInlineBox::buildLayoutInformationForTextBox): Account for multichar glyphs - let glyph
+ selection consider extra chars, and account for the fact that a glyph may have consumed multiple chars.
+ * rendering/SVGRootInlineBox.h:
+ * svg/SVGFont.cpp:
+ (WebCore::SVGTextRunWalker::walk): This is the place where glyph selection happens, so this is where
+ we accout for multichar glyphs (both looking at extra chars past the end of the run, and reporting how
+ many chars were consumed).
+ (WebCore::floatWidthOfSubStringUsingSVGFont): Pass aforementioned info through the layers.
+ (WebCore::Font::floatWidthUsingSVGFont): ditto
+ (WebCore::Font::drawTextUsingSVGFont): ditto
+ (WebCore::Font::selectionRectForTextUsingSVGFont): ditto
+ * svg/SVGTextContentElement.cpp:
+ (WebCore::cummulatedCharacterRangeLength): ditto
+ (WebCore::SVGInlineTextBoxQueryWalker::chunkPortionCallback): ditto
+
2008-03-25 Beth Dakin <bdakin@apple.com>
Reviewed by Oliver.
return floatWidthForComplexText(run);
}
+float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed) const
+{
+#if ENABLE(SVG_FONTS)
+ if (primaryFont()->isSVGFont())
+ return floatWidthUsingSVGFont(run, extraCharsAvailable, charsConsumed);
+#endif
+
+ charsConsumed = run.length();
+ if (canUseGlyphCache(run))
+ return floatWidthForSimpleText(run, 0);
+ return floatWidthForComplexText(run);
+}
+
float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer) const
{
WidthIterator it(this, run);
int width(const TextRun&) const;
float floatWidth(const TextRun&) const;
+ float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed) const;
int offsetForPosition(const TextRun&, int position, bool includePartialGlyphs) const;
FloatRect selectionRectForText(const TextRun&, const IntPoint&, int h, int from = 0, int to = -1) const;
#if ENABLE(SVG_FONTS)
void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
float floatWidthUsingSVGFont(const TextRun&) const;
+ float floatWidthUsingSVGFont(const TextRun&, int extraCharsAvailable, int& charsConsumed) const;
FloatRect selectionRectForTextUsingSVGFont(const TextRun&, const IntPoint&, int h, int from, int to) const;
int offsetForPositionForTextUsingSVGFont(const TextRun&, int position, bool includePartialGlyphs) const;
#endif
return static_cast<SVGRootInlineBox*>(parentBox);
}
-float SVGInlineTextBox::calculateGlyphWidth(RenderStyle* style, int offset) const
+float SVGInlineTextBox::calculateGlyphWidth(RenderStyle* style, int offset, int extraCharsAvailable, int& charsConsumed) const
{
ASSERT(style);
- return style->font().floatWidth(svgTextRunForInlineTextBox(textObject()->text()->characters() + offset, 1, style, this, 0));
+ return style->font().floatWidth(svgTextRunForInlineTextBox(textObject()->text()->characters() + offset, 1, style, this, 0), extraCharsAvailable, charsConsumed);
}
-float SVGInlineTextBox::calculateGlyphHeight(RenderStyle* style, int offset) const
+float SVGInlineTextBox::calculateGlyphHeight(RenderStyle* style, int offset, int extraCharsAvailable) const
{
ASSERT(style);
// Take RTL text into account and pick right glyph width/height.
float glyphWidth = 0.0f;
+ // FIXME: account for multi-character glyphs
+ int charsConsumed;
if (!m_reversed)
- glyphWidth = calculateGlyphWidth(style, offset);
+ glyphWidth = calculateGlyphWidth(style, offset, 0, charsConsumed);
else
- glyphWidth = calculateGlyphWidth(style, start() + end() - offset);
+ glyphWidth = calculateGlyphWidth(style, start() + end() - offset, 0, charsConsumed);
float x1 = svgChar.x;
float x2 = svgChar.x + glyphWidth;
SVGRootInlineBox* svgRootInlineBox() const;
// Helper functions shared with SVGRootInlineBox
- float calculateGlyphWidth(RenderStyle*, int offset) const;
- float calculateGlyphHeight(RenderStyle*, int offset) const;
+ float calculateGlyphWidth(RenderStyle* style, int offset, int extraCharsAvailable, int& charsConsumed) const;
+ float calculateGlyphHeight(RenderStyle*, int offset, int extraCharsAvailable) const;
FloatRect calculateGlyphBoundaries(RenderStyle*, int offset, const SVGChar&) const;
SVGChar* closestCharacterToPosition(int x, int y, int& offset) const;
int offset = box->m_reversed ? box->end() - i - positionOffset + 1 : box->start() + i + positionOffset - 1;
+ // FIXME: does this need to change to handle multichar glyphs?
+ int charsConsumed = 1;
if (calcWidthOnly) {
- float lastGlyphWidth = box->calculateGlyphWidth(style, offset);
+ float lastGlyphWidth = box->calculateGlyphWidth(style, offset, 0, charsConsumed);
length += currentCharacter.x - lastCharacter.x - lastGlyphWidth;
} else {
- float lastGlyphHeight = box->calculateGlyphHeight(style, offset);
+ float lastGlyphHeight = box->calculateGlyphHeight(style, offset, 0);
length += currentCharacter.y - lastCharacter.y - lastGlyphHeight;
}
}
const SVGRenderStyle* svgStyle = style->svgStyle();
bool isVerticalText = isVerticalWritingMode(svgStyle);
- for (unsigned i = 0; i < length; ++i) {
+ int charsConsumed = 0;
+ for (unsigned i = 0; i < length; i += charsConsumed) {
SVGChar svgChar;
if (info.inPathLayout())
float glyphWidth = 0.0f;
float glyphHeight = 0.0f;
+ int extraCharsAvailable = length - i - 1;
+
if (textBox->m_reversed) {
- glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->end() - i);
- glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->end() - i);
+ glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->end() - i, extraCharsAvailable, charsConsumed);
+ glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->end() - i, extraCharsAvailable);
} else {
- glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->start() + i);
- glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->start() + i);
+ glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->start() + i, extraCharsAvailable, charsConsumed);
+ glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->start() + i, extraCharsAvailable);
}
bool assignedX = false;
} else
info.curx += glyphAdvance + spacing;
- // Advance to next character
- info.svgChars.append(svgChar);
- info.processedSingleCharacter();
+ // Advance to next character group
+ for (int k = 0; k < charsConsumed; ++k) {
+ info.svgChars.append(svgChar);
+ info.processedSingleCharacter();
+ svgChar.drawnSeperated = false;
+ svgChar.newTextChunk = false;
+ }
}
}
SVGGlyphIdentifier identifier;
bool foundGlyph = false;
int characterLookupRange;
+ int endOfScanRange = to + m_walkerData.extraCharsAvailable;
for (int i = from; i < to; ++i) {
// If characterLookupRange is > 0, then the font defined ligatures (length of unicode property value > 1).
// We have to check wheter the current character & the next character define a ligature. This needs to be
// extended to the n-th next character (where n is 'characterLookupRange'), to check for any possible ligature.
- characterLookupRange = maximumHashKeyLength + i >= to ? to - i : maximumHashKeyLength;
+ characterLookupRange = maximumHashKeyLength + i >= endOfScanRange ? endOfScanRange - i : maximumHashKeyLength;
+ // FIXME: instead of checking from longest string to shortest, this should really scan in order
+ // of the glyphs and pick the first match
while (characterLookupRange > 0 && !foundGlyph) {
String lookupString(run.data(run.rtl() ? run.length() - (i + characterLookupRange) : i), characterLookupRange);
if (identifier.isValid && isCompatibleGlyph(identifier, isVerticalText, language, chars, startPosition, endPosition)) {
ASSERT(characterLookupRange > 0);
i += characterLookupRange - 1;
+ m_walkerData.charsConsumed += characterLookupRange;
foundGlyph = true;
SVGGlyphElement::inheritUnspecifiedAttributes(identifier, m_fontData);
}
if (!foundGlyph) {
+ ++m_walkerData.charsConsumed;
if (SVGMissingGlyphElement* element = m_fontElement->firstMissingGlyphElement()) {
// <missing-glyph> element support
identifier = SVGGlyphElement::buildGenericGlyphIdentifier(element);
int at;
int from;
int to;
+ int extraCharsAvailable;
+ int charsConsumed;
float scale;
float length;
data.length += font.floatWidth(run);
}
-static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& run, int from, int to)
+static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& run, int extraCharsAvailable, int from, int to, int& charsConsumed)
{
int newFrom = to > from ? from : to;
int newTo = to > from ? to : from;
data.at = from;
data.from = from;
data.to = to;
+ data.extraCharsAvailable = extraCharsAvailable;
+ data.charsConsumed = 0;
data.scale = convertEmUnitToPixel(font->size(), fontFaceElement->unitsPerEm(), 1.0f);
data.length = 0.0f;
SVGTextRunWalker<SVGTextRunWalkerMeasuredLengthData> runWalker(fontData, fontElement, data, floatWidthUsingSVGFontCallback, floatWidthMissingGlyphCallback);
runWalker.walk(run, isVerticalText, language, 0, run.length());
+ charsConsumed = data.charsConsumed;
return data.length;
}
float Font::floatWidthUsingSVGFont(const TextRun& run) const
{
- return floatWidthOfSubStringUsingSVGFont(this, run, 0, run.length());
+ int charsConsumed;
+ return floatWidthOfSubStringUsingSVGFont(this, run, 0, 0, run.length(), charsConsumed);
+}
+
+float Font::floatWidthUsingSVGFont(const TextRun& run, int extraCharsAvailable, int& charsConsumed) const
+{
+ return floatWidthOfSubStringUsingSVGFont(this, run, extraCharsAvailable, 0, run.length(), charsConsumed);
}
// Callback & data structures to draw text using SVG Fonts
struct SVGTextRunWalkerDrawTextData {
float scale;
bool isVerticalText;
+ int extraCharsAvailable;
+ int charsConsumed;
float xStartOffset;
FloatPoint currentPoint;
ASSERT(data.activePaintServer);
+ int charsConsumed;
data.isVerticalText = false;
- data.xStartOffset = floatWidthOfSubStringUsingSVGFont(this, run, run.rtl() ? to : 0, run.rtl() ? run.length() : from);
+ data.xStartOffset = floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed);
data.glyphOrigin = FloatPoint();
data.context = context;
data.glyphOrigin.setY(fontData->horizontalOriginY() * data.scale);
}
+ data.extraCharsAvailable = 0;
+
SVGTextRunWalker<SVGTextRunWalkerDrawTextData> runWalker(fontData, fontElement, data, drawTextUsingSVGFontCallback, drawTextMissingGlyphCallback);
runWalker.walk(run, data.isVerticalText, language, from, to);
}
FloatRect Font::selectionRectForTextUsingSVGFont(const TextRun& run, const IntPoint& point, int height, int from, int to) const
{
- return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(this, run, run.rtl() ? to : 0, run.rtl() ? run.length() : from),
- point.y(), floatWidthOfSubStringUsingSVGFont(this, run, from, to), height);
+ int charsConsumed;
+ return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed),
+ point.y(), floatWidthOfSubStringUsingSVGFont(this, run, 0, from, to, charsConsumed), height);
}
int Font::offsetForPositionForTextUsingSVGFont(const TextRun&, int position, bool includePartialGlyphs) const
SVGGlyphIdentifier()
: isValid(false)
+ , priority(0)
, orientation(Both)
, arabicForm(None)
, horizontalAdvanceX(0.0f)
}
bool isValid : 1;
+ int priority;
Orientation orientation : 2;
ArabicForm arabicForm : 3;
if (textBox->m_reversed)
newOffset = textBox->start() + textBox->end() - newOffset;
+ // FIXME: does this handle multichar glyphs ok? not sure
+ int charsConsumed = 0;
if (isVerticalText)
- textLength += textBox->calculateGlyphHeight(style, newOffset);
+ textLength += textBox->calculateGlyphHeight(style, newOffset, 0);
else
- textLength += textBox->calculateGlyphWidth(style, newOffset);
+ textLength += textBox->calculateGlyphWidth(style, newOffset, 0, charsConsumed);
}
if (!usesFullRange) {
if (textBox->m_reversed)
newOffset = textBox->start() + textBox->end() - newOffset;
+ int charsConsumed;
if (isVerticalText)
- m_queryPointResult.move(it->x, it->y + textBox->calculateGlyphHeight(style, newOffset));
+ m_queryPointResult.move(it->x, it->y + textBox->calculateGlyphHeight(style, newOffset, end - it));
else
- m_queryPointResult.move(it->x + textBox->calculateGlyphWidth(style, newOffset), it->y);
+ m_queryPointResult.move(it->x + textBox->calculateGlyphWidth(style, newOffset, end - it, charsConsumed), it->y);
m_stopProcessing = true;
return;