1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
// Code generated by running "go run gen.go -core" in golang.org/x/text. DO NOT EDIT.
// +build ignore
package bidi_test
import (
"fmt"
"log"
"golang_org/x/text/bidi"
)
func foo() {
var sa StringAttributes
var p Paragraph
n, _ := p.SetString(s)
for i, o := 0, p.Ordering(); i < o.NumRuns(); i++ {
b := o.Run(i).Bytes()
start, end := o.Run(i).Pos()
for p := start; p < end; {
style, n := sa.StyleAt(start)
render()
p += n
}
}
}
type style int
const (
styleNormal = 0
styleSelected = 1 << (iota - 1)
styleBold
styleItalics
)
type styleRun struct {
end int
style style
}
func getTextWidth(text string, styleRuns []styleRun) int {
// simplistic way to compute the width
return len([]rune(text))
}
// set limit and StyleRun limit for a line
// from text[start] and from styleRuns[styleRunStart]
// using Bidi.getLogicalRun(...)
// returns line width
func getLineBreak(p *bidi.Paragraph, start int, styles []styleRun) (n int) {
// dummy return
return 0
}
// render runs on a line sequentially, always from left to right
// prepare rendering a new line
func startLine(d bidi.Direction, lineWidth int) {
fmt.Println()
}
// render a run of text and advance to the right by the run width
// the text[start..limit-1] is always in logical order
func renderRun(text string, d bidi.Direction, styl style) {
}
// We could compute a cross-product
// from the style runs with the directional runs
// and then reorder it.
// Instead, here we iterate over each run type
// and render the intersections -
// with shortcuts in simple (and common) cases.
// renderParagraph() is the main function.
// render a directional run with
// (possibly) multiple style runs intersecting with it
func renderDirectionalRun(text string, offset int, d bidi.Direction, styles []styleRun) {
start, end := offset, len(text)+offset
// iterate over style runs
if run.Direction() == bidi.LeftToRight {
styleEnd := 0
for _, sr := range styles {
styleEnd = styleRuns[i].end
if start < styleEnd {
if styleEnd > end {
styleEnd = end
}
renderRun(text[start-offset:styleEnd-offset], run.Direction(), styles[i].style)
if styleEnd == end {
break
}
start = styleEnd
}
}
} else {
styleStart := 0
for i := len(styles) - 1; i >= 0; i-- {
if i > 0 {
styleStart = styles[i-1].end
} else {
styleStart = 0
}
if end >= styleStart {
if styleStart < start {
styleStart = start
}
renderRun(text[styleStart-offset:end-offset], run.Direction(), styles[i].style)
if styleStart == start {
break
}
end = styleStart
}
}
}
}
// the line object represents text[start..limit-1]
func renderLine(line *bidi.Runs, text string, offset int, styles []styleRun) {
if dir := line.Direction(); dir != bidi.Mixed {
if len(styles) == 1 {
renderRun(text, dir, styles[0].style)
} else {
for i := 0; i < line.NumRuns(); i++ {
renderDirectionalRun(text, offset, dir, styles)
}
}
} else {
// iterate over both directional and style runs
for i := 0; i < line.Len(); i++ {
run := line.Run(i)
start, _ := run.Pos()
renderDirectionalRun(text[start-offset:], start, run.Direction(), styles)
}
}
}
func renderParagraph(text string, d bidi.Direction, styles []styleRun, int lineWidth) {
var p bidi.Paragraph
if err := p.SetString(text, bidi.DefaultDirection(d)); err != nil {
log.Fatal(err)
}
if len(styles) == 0 {
styles = append(styles, []styleRun{len(text), styleNormal})
}
if width := getTextWidth(text, styles); width <= lineWidth {
// everything fits onto one line
runs, err := p.Runs()
if err != nil {
log.Fatal(err)
}
// prepare rendering a new line from either left or right
startLine(p.Direction(), width)
renderLine(&runs, text, styles)
} else {
// we need to render several lines
for start, end := 0, 0; start < len(text); start = end {
for start >= styles[0].end {
styles = styles[1:]
}
end = getLineBreak(p, start, styles[startStyles:])
runs, err := p.Line(start, end)
if err != nil {
log.Fatal(err)
}
startLine(p.Direction(), end-start)
renderLine(&runs, text[start:end], styles[startStyles:])
}
}
}
func main() {
renderParagraph("Some Latin text...", bidi.LeftToRight, nil, 80)
renderParagraph("Some Hebrew text...", bidi.RightToLeft, nil, 60)
}
|