| 1255 | } |
| 1256 | |
| 1257 | func (t *Text) renderLineTo(r Renderer, m Matrix, resolution Resolution, index int, renderText, renderDeco bool) { |
| 1258 | line := t.lines[index] |
| 1259 | ps := make([]*Path, len(line.spans)) |
| 1260 | xs := make([]float64, len(line.spans)) |
| 1261 | ys := make([]float64, len(line.spans)) |
| 1262 | for i, span := range line.spans { |
| 1263 | x, y := span.X, -line.y |
| 1264 | if t.WritingMode != HorizontalTB { |
| 1265 | x, y = line.y, -span.X |
| 1266 | } |
| 1267 | if resolution != 0.0 && span.Face.Hinting != font.NoHinting && span.Rotation == text.NoRotation && Equal(m[1][0], 0.0) { |
| 1268 | // grid-align vertically on pixel raster, this improves font sharpness |
| 1269 | _, dy := m.Pos() |
| 1270 | dy += y |
| 1271 | y += float64(int(dy*resolution.DPMM()+0.5))/resolution.DPMM() - dy |
| 1272 | } |
| 1273 | xs[i] = x |
| 1274 | ys[i] = y |
| 1275 | if span.IsText() { |
| 1276 | ps[i], _ = span.Face.toPath(span.Glyphs, span.Face.PPEM(resolution)) |
| 1277 | } |
| 1278 | } |
| 1279 | |
| 1280 | // render decorations |
| 1281 | if renderDeco { |
| 1282 | handled := make([][]bool, len(line.spans)) |
| 1283 | for i, span := range line.spans { |
| 1284 | for k, deco := range line.spans[i].Face.Deco { |
| 1285 | if handled[i] != nil && handled[i][k] { |
| 1286 | continue |
| 1287 | } |
| 1288 | p := ps[i] |
| 1289 | j := i + 1 |
| 1290 | FindEnd: |
| 1291 | for ; j < len(line.spans); j++ { |
| 1292 | for k, deco2 := range line.spans[j].Face.Deco { |
| 1293 | if reflect.DeepEqual(deco2, deco) && ys[j] == ys[i] && line.spans[j].Rotation == span.Rotation { |
| 1294 | if handled[j] == nil { |
| 1295 | handled[j] = make([]bool, len(line.spans[j].Face.Deco)) |
| 1296 | } |
| 1297 | handled[j][k] = true |
| 1298 | if span.IsText() { |
| 1299 | p = p.Append(ps[i].Translate(xs[j]-xs[i], 0.0)) |
| 1300 | } |
| 1301 | continue FindEnd |
| 1302 | } |
| 1303 | } |
| 1304 | break |
| 1305 | } |
| 1306 | lastSpan := line.spans[j-1] |
| 1307 | deco.Decorate(r, m.Translate(xs[i], ys[i]).Rotate(float64(span.Rotation)), span.Face, p, lastSpan.X+lastSpan.Width-span.X) |
| 1308 | } |
| 1309 | } |
| 1310 | } |
| 1311 | |
| 1312 | if renderText { |
| 1313 | for i, span := range line.spans { |
| 1314 | if span.IsText() { |