// rshapes draws shapes with random colors, openvg.Strokes, and sizes. func rshapes(width, height, n int) { var sx, sy, cx, cy, px, py, ex, ey, pox, poy openvg.VGfloat np := 10 polyx := make([]openvg.VGfloat, np) polyy := make([]openvg.VGfloat, np) openvg.Start(width, height) for i := 0; i < n; i++ { openvg.FillRGB(randcolor(), randcolor(), randcolor(), openvg.VGfloat(rand.Float32())) openvg.Ellipse(randf(width), randf(height), randf(200), randf(100)) openvg.Circle(randf(width), randf(height), randf(100)) openvg.Rect(randf(width), randf(height), randf(200), randf(100)) openvg.Arc(randf(width), randf(height), randf(200), randf(200), randf(360), randf(360)) sx = randf(width) sy = randf(height) openvg.StrokeRGB(randcolor(), randcolor(), randcolor(), 1) openvg.StrokeWidth(randf(5)) openvg.Line(sx, sy, sx+randf(200), sy+randf(100)) openvg.StrokeWidth(0) sx = randf(width) sy = randf(height) ex = sx + randf(200) ey = sy cx = sx + ((ex - sx) / 2.0) cy = sy + randf(100) openvg.Qbezier(sx, sy, cx, cy, ex, ey) sx = randf(width) sy = randf(height) ex = sx + randf(200) ey = sy cx = sx + ((ex - sx) / 2.0) cy = sy + randf(100) px = cx py = sy - randf(100) openvg.Cbezier(sx, sy, cx, cy, px, py, ex, ey) pox = randf(width) poy = randf(height) for j := 0; j < np; j++ { polyx[j] = pox + randf(200) polyy[j] = poy + randf(100) } openvg.Polygon(polyx, polyy) // , np) pox = randf(width) poy = randf(height) for j := 0; j < np; j++ { polyx[j] = pox + randf(200) polyy[j] = poy + randf(100) } openvg.Polyline(polyx, polyy) // , np) } openvg.FillRGB(128, 0, 0, 1) openvg.Text(20, 20, "OpenVG on the Raspberry Pi", "sans", 32) openvg.End() }
// fontrange shows a range of fonts func fontrange(w, h int) { var x, lx, length openvg.VGfloat y := openvg.VGfloat(h) / 2.0 w2 := openvg.VGfloat(w) / 2.0 spacing := openvg.VGfloat(50.0) s2 := spacing / 2.0 sizes := []int{6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 24, 36, 48, 60, 72, 96} openvg.Start(w, h) openvg.Background(255, 255, 255) // compute the length so we can center length = 0.0 for _, s := range sizes { length += openvg.VGfloat(s) + spacing } length -= spacing lx = w2 - (length / 2) // center point // for each size, display a character and label x = lx for _, s := range sizes { openvg.FillRGB(128, 0, 0, 1) openvg.TextMid(x, y, "a", "serif", s) openvg.FillRGB(128, 128, 128, 1) openvg.TextMid(x, y-spacing, fmt.Sprintf("%d", s), "sans", 16) x += openvg.VGfloat(s) + spacing } // draw a openvg.Line below the characters, a curve above x -= spacing openvg.StrokeRGB(150, 150, 150, 0.5) openvg.StrokeWidth(2) openvg.Line(lx, y-s2, x, y-s2) openvg.FillRGB(255, 255, 255, 1) openvg.Qbezier(lx, y+s2, x, y+s2, x, y+(spacing*3)) openvg.End() }
// refcard shows a reference card of shapes func refcard(width, height int) { shapenames := []string{ "Circle", "Ellipse", "Rectangle", "Rounded Rectangle", "Line", "Polyline", "Polygon", "Arc", "Quadratic Bezier", "Cubic Bezier", "Image", } top := openvg.VGfloat(height) * .95 sx := openvg.VGfloat(width) * 0.10 sy := top sw := openvg.VGfloat(width) * .05 sh := openvg.VGfloat(height) * .045 dotsize := openvg.VGfloat(7.0) spacing := openvg.VGfloat(2.0) fontsize := int(openvg.VGfloat(height) * .033) shapecolor := Color{202, 225, 255, 1.0} openvg.Start(width, height) openvg.FillRGB(128, 0, 0, 1) openvg.TextEnd(openvg.VGfloat(width-20), openvg.VGfloat(height/2), "OpenVG on the Raspberry Pi", "sans", fontsize+(fontsize/2)) openvg.FillRGB(0, 0, 0, 1) for _, s := range shapenames { openvg.Text(sx+sw+sw/2, sy, s, "sans", fontsize) sy -= sh * spacing } sy = top cx := sx + (sw / 2) ex := sx + sw openvg.FillRGB(shapecolor.red, shapecolor.green, shapecolor.blue, shapecolor.alpha) openvg.Circle(cx, sy, sw) coordpoint(cx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.Ellipse(cx, sy, sw, sh) coordpoint(cx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.Rect(sx, sy, sw, sh) coordpoint(sx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.Roundrect(sx, sy, sw, sh, 20, 20) coordpoint(sx, sy, dotsize, shapecolor) sy -= sh * spacing openvg.StrokeWidth(1) openvg.StrokeRGB(204, 204, 204, 1) openvg.Line(sx, sy, ex, sy) coordpoint(sx, sy, dotsize, shapecolor) coordpoint(ex, sy, dotsize, shapecolor) sy -= sh px := []openvg.VGfloat{sx, sx + (sw / 4), sx + (sw / 2), sx + ((sw * 3) / 4), sx + sw} py := []openvg.VGfloat{sy, sy - sh, sy, sy - sh, sy} openvg.Polyline(px, py) // , 5) coordpoint(px[0], py[0], dotsize, shapecolor) coordpoint(px[1], py[1], dotsize, shapecolor) coordpoint(px[2], py[2], dotsize, shapecolor) coordpoint(px[3], py[3], dotsize, shapecolor) coordpoint(px[4], py[4], dotsize, shapecolor) sy -= sh * spacing py[0] = sy py[1] = sy - sh py[2] = sy - (sh / 2) py[3] = py[1] - (sh / 4) py[4] = sy openvg.Polygon(px, py) // , 5) sy -= (sh * spacing) + sh openvg.Arc(sx+(sw/2), sy, sw, sh, 0, 180) coordpoint(sx+(sw/2), sy, dotsize, shapecolor) sy -= sh * spacing var cy, ey openvg.VGfloat cy = sy + (sh / 2) ey = sy openvg.Qbezier(sx, sy, cx, cy, ex, ey) coordpoint(sx, sy, dotsize, shapecolor) coordpoint(cx, cy, dotsize, shapecolor) coordpoint(ex, ey, dotsize, shapecolor) sy -= sh * spacing ey = sy cy = sy + sh openvg.Cbezier(sx, sy, cx, cy, cx, sy, ex, ey) coordpoint(sx, sy, dotsize, shapecolor) coordpoint(cx, cy, dotsize, shapecolor) coordpoint(cx, sy, dotsize, shapecolor) coordpoint(ex, ey, dotsize, shapecolor) sy -= (sh * spacing * 1.5) openvg.Image(sx, sy, 110, 110, "starx.jpg") openvg.End() }
// showlide displays slides func showslide(d deck.Deck, imap map[string]image.Image, n int) { var video videoType if n < 0 || n > len(d.Slide)-1 { return } slide := d.Slide[n] if slide.Bg == "" { slide.Bg = "white" } if slide.Fg == "" { slide.Fg = "black" } openvg.Start(d.Canvas.Width, d.Canvas.Height) cw := openvg.VGfloat(d.Canvas.Width) ch := openvg.VGfloat(d.Canvas.Height) if slide.Gradcolor1 != "" && slide.Gradcolor2 != "" { oc := []openvg.Offcolor{ {0, openvg.Colorlookup(slide.Gradcolor1), 1}, {1, openvg.Colorlookup(slide.Gradcolor2), 1}, } openvg.FillLinearGradient(0, ch, 0, 0, oc) } else { openvg.FillColor(slide.Bg) } openvg.Rect(0, 0, cw, ch) var x, y, fs openvg.VGfloat // every image in the slide for _, im := range slide.Image { x = pct(im.Xp, cw) y = pct(im.Yp, ch) imw := openvg.VGfloat(im.Width) imh := openvg.VGfloat(im.Height) if im.Scale > 0 { imw *= openvg.VGfloat(im.Scale / 100) imh *= openvg.VGfloat(im.Scale / 100) } midx := openvg.VGfloat(imw / 2) midy := openvg.VGfloat(imh / 2) if im.Type == "video" { // Only one video per slide supported video.name = im.Name video.x = x - midx video.y = y - midy video.w = imw video.h = imh video.altimg = im.Link } else { img, ok := imap[im.Name] if ok { openvg.Img(x-midx, y-midy, img) } if len(im.Caption) > 0 { capfs := pctwidth(im.Sp, cw, cw/100) if im.Font == "" { im.Font = "sans" } if im.Color == "" { openvg.FillColor(slide.Fg) } else { openvg.FillColor(im.Color) } if im.Align == "" { im.Align = "center" } switch im.Align { case "left", "start": x -= midx case "right", "end": x += midx } showtext(x, y-((midy)+(capfs*2.0)), im.Caption, im.Align, im.Font, capfs) } } } // every graphic on the slide const defaultColor = "rgb(127,127,127)" const defaultSw = 1.5 var strokeopacity float64 // line for _, line := range slide.Line { if line.Color == "" { line.Color = slide.Fg // defaultColor } if line.Opacity == 0 { strokeopacity = 1 } else { strokeopacity = line.Opacity / 100.0 } x1, y1, sw := dimen(d, line.Xp1, line.Yp1, line.Sp) x2, y2, _ := dimen(d, line.Xp2, line.Yp2, 0) openvg.StrokeColor(line.Color, openvg.VGfloat(strokeopacity)) if sw == 0 { sw = defaultSw } openvg.StrokeWidth(openvg.VGfloat(sw)) openvg.StrokeColor(line.Color) openvg.Line(x1, y1, x2, y2) openvg.StrokeWidth(0) } // ellipse for _, ellipse := range slide.Ellipse { x, y, _ = dimen(d, ellipse.Xp, ellipse.Yp, 0) var w, h openvg.VGfloat w = pct(ellipse.Wp, cw) if ellipse.Hr == 0 { // if relative height not specified, base height on overall height h = pct(ellipse.Hp, ch) } else { h = pct(ellipse.Hr, w) } if ellipse.Color == "" { ellipse.Color = defaultColor } if ellipse.Opacity == 0 { ellipse.Opacity = 1 } else { ellipse.Opacity /= 100 } openvg.FillColor(ellipse.Color, openvg.VGfloat(ellipse.Opacity)) openvg.Ellipse(x, y, w, h) } // rect for _, rect := range slide.Rect { x, y, _ = dimen(d, rect.Xp, rect.Yp, 0) var w, h openvg.VGfloat w = pct(rect.Wp, cw) if rect.Hr == 0 { // if relative height not specified, base height on overall height h = pct(rect.Hp, ch) } else { h = pct(rect.Hr, w) } if rect.Color == "" { rect.Color = defaultColor } if rect.Opacity == 0 { rect.Opacity = 1 } else { rect.Opacity /= 100 } openvg.FillColor(rect.Color, openvg.VGfloat(rect.Opacity)) openvg.Rect(x-(w/2), y-(h/2), w, h) } // curve for _, curve := range slide.Curve { if curve.Color == "" { curve.Color = defaultColor } if curve.Opacity == 0 { strokeopacity = 1 } else { strokeopacity = curve.Opacity / 100.0 } x1, y1, sw := dimen(d, curve.Xp1, curve.Yp1, curve.Sp) x2, y2, _ := dimen(d, curve.Xp2, curve.Yp2, 0) x3, y3, _ := dimen(d, curve.Xp3, curve.Yp3, 0) openvg.StrokeColor(curve.Color, openvg.VGfloat(strokeopacity)) openvg.FillColor(slide.Bg, openvg.VGfloat(curve.Opacity)) if sw == 0 { sw = defaultSw } openvg.StrokeWidth(sw) openvg.Qbezier(x1, y1, x2, y2, x3, y3) openvg.StrokeWidth(0) } // arc for _, arc := range slide.Arc { if arc.Color == "" { arc.Color = defaultColor } if arc.Opacity == 0 { strokeopacity = 1 } else { strokeopacity = arc.Opacity / 100.0 } ax, ay, sw := dimen(d, arc.Xp, arc.Yp, arc.Sp) w := pct(arc.Wp, cw) h := pct(arc.Hp, cw) openvg.StrokeColor(arc.Color, openvg.VGfloat(strokeopacity)) openvg.FillColor(slide.Bg, openvg.VGfloat(arc.Opacity)) if sw == 0 { sw = defaultSw } openvg.StrokeWidth(sw) openvg.Arc(ax, ay, w, h, openvg.VGfloat(arc.A1), openvg.VGfloat(arc.A2)) openvg.StrokeWidth(0) } // polygon for _, poly := range slide.Polygon { if poly.Color == "" { poly.Color = defaultColor } if poly.Opacity == 0 { poly.Opacity = 1 } else { poly.Opacity /= 100 } xs := strings.Split(poly.XC, " ") ys := strings.Split(poly.YC, " ") if len(xs) != len(ys) { continue } if len(xs) < 3 || len(ys) < 3 { continue } px := make([]openvg.VGfloat, len(xs)) py := make([]openvg.VGfloat, len(ys)) for i := 0; i < len(xs); i++ { x, err := strconv.ParseFloat(xs[i], 32) if err != nil { px[i] = 0 } else { px[i] = pct(x, cw) } y, err := strconv.ParseFloat(ys[i], 32) if err != nil { py[i] = 0 } else { py[i] = pct(y, ch) } } openvg.FillColor(poly.Color, openvg.VGfloat(poly.Opacity)) openvg.Polygon(px, py) } openvg.FillColor(slide.Fg) // every list in the slide var offset, textopacity openvg.VGfloat const blinespacing = 2.4 for _, l := range slide.List { if l.Font == "" { l.Font = "sans" } x, y, fs = dimen(d, l.Xp, l.Yp, l.Sp) if l.Type == "bullet" { offset = 1.2 * fs } else { offset = 0 } if l.Lp == 0 { l.Lp = blinespacing } if l.Opacity == 0 { textopacity = 1 } else { textopacity = openvg.VGfloat(l.Opacity / 100) } // every list item var li, lifont string for ln, tl := range l.Li { if len(l.Color) > 0 { openvg.FillColor(l.Color, textopacity) } else { openvg.FillColor(slide.Fg) } if l.Type == "bullet" { boffset := fs / 2 openvg.Ellipse(x, y+boffset, boffset, boffset) //openvg.Rect(x, y+boffset/2, boffset, boffset) } if l.Type == "number" { li = fmt.Sprintf("%d. ", ln+1) + tl.ListText } else { li = tl.ListText } if len(tl.Color) > 0 { openvg.FillColor(tl.Color, textopacity) } if len(tl.Font) > 0 { lifont = tl.Font } else { lifont = l.Font } showtext(x+offset, y, li, l.Align, lifont, fs) y -= fs * openvg.VGfloat(l.Lp) } } openvg.FillColor(slide.Fg) // every text in the slide const linespacing = 1.8 var tdata string for _, t := range slide.Text { if t.File != "" { tdata = includefile(t.File) } else { tdata = t.Tdata } if t.Font == "" { t.Font = "sans" } if t.Opacity == 0 { textopacity = 1 } else { textopacity = openvg.VGfloat(t.Opacity / 100) } if t.Lp == 0 { t.Lp = linespacing } x, y, fs = dimen(d, t.Xp, t.Yp, t.Sp) td := strings.Split(tdata, "\n") if t.Type == "code" { ls := fs * openvg.VGfloat(t.Lp) t.Font = "mono" tdepth := (ls * openvg.VGfloat(len(td))) + fs openvg.FillColor("rgb(240,240,240)") openvg.Rect(x-20, y-tdepth+(ls), pctwidth(t.Wp, cw, cw-x-20), tdepth) } if t.Color == "" { openvg.FillColor(slide.Fg, textopacity) } else { openvg.FillColor(t.Color, textopacity) } if t.Type == "block" { textwrap(x, y, pctwidth(t.Wp, cw, cw/2), tdata, t.Font, fs, fs*openvg.VGfloat(t.Lp), 0.3) } else { // every text line ls := fs * openvg.VGfloat(t.Lp) for _, txt := range td { showtext(x, y, txt, t.Align, t.Font, fs) y -= ls } } } openvg.FillColor(slide.Fg) openvg.End() if video.altimg != "" { img, ok := imap[video.altimg] if ok { openvg.Img(video.x, video.y, img) } } if video.name != "" { openvg.Video(video.x, video.y, video.w, video.h, video.name) } }