func main() { var loop = flag.Bool("loop", false, "Loop the show") var resize = flag.Bool("resize", false, `Resize image to fit the screen.`) var bgcolor = flag.String("bg", "black", `Background color (named color or rgb(r,g,b)).`) var delay = flag.Duration("delay", 2*time.Second, "Delay between pictures") flag.Usage = func() { fmt.Fprintf(os.Stderr, "usage: %s [ flags ] images...\n", os.Args[0]) flag.PrintDefaults() os.Exit(1) } flag.Parse() w, h := openvg.Init() images := []image.Image{} imgcount := 0 for _, imgfile := range flag.Args() { fmt.Fprintf(os.Stderr, "loading %q ", imgfile) img, err := getimage(imgfile, w, h, *resize) if err != nil { fmt.Fprintln(os.Stderr, err) continue } images = append(images, img) imgcount++ fmt.Fprintln(os.Stderr, "ok") } for { for _, img := range images { ib := img.Bounds() imw, imh := ib.Max.X-ib.Min.X, ib.Max.Y-ib.Min.Y openvg.Start(w, h) openvg.BackgroundColor(*bgcolor) x, y := openvg.VGfloat(w)/2-openvg.VGfloat(imw)/2, openvg.VGfloat(h)/2-openvg.VGfloat(imh)/2 openvg.Img(x, y, img) openvg.End() time.Sleep(*delay) } if !*loop { break } } }
func main() { var resize = flag.Bool("resize", false, "Resize image to fit the screen.") var bgcolor = flag.String("bg", "black", "Background color (named color or rgb(r,g,b)).") var fgcolor = flag.String("fg", "white", "text color (named color or rgb(r,g,b)).") var title = flag.String("t", "", "text annotation") var fontsize = flag.Float64("fp", 2.0, "fontsize %") var px = flag.Float64("px", 50, "x position %") var py = flag.Float64("py", 50, "y position %") var texty = flag.Float64("ty", 0, "text y %") var exit_code int defer func() { os.Exit(exit_code) }() flag.Usage = func() { fmt.Fprintf(os.Stderr, `usage: %s [ flags ] image-path Set specified image as an overlay screen via OpenVG lib. Default is to put this image to the center. `, os.Args[0]) flag.PrintDefaults() exit_code = 1 return } flag.Parse() if flag.NArg() != 1 { fmt.Fprintf(os.Stderr, "Exactly one image-path argument must be specified.\n") flag.Usage() exit_code = 2 return } openvg.SaveTerm() w, h := openvg.Init() openvg.RawTerm() defer openvg.Finish() defer openvg.RestoreTerm() img, err := getimage(flag.Args()[0], w, h, *resize) if err != nil { exit_code = 3 return } ib := img.Bounds() imw, imh := ib.Max.X-ib.Min.X, ib.Max.Y-ib.Min.Y sig_chan := make(chan os.Signal, 1) signal.Notify(sig_chan, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGALRM) openvg.Start(w, h) openvg.BackgroundColor(*bgcolor) var x, y openvg.VGfloat if *px < 0 || *px > 100 { x = openvg.VGfloat(w)/2 - openvg.VGfloat(imw)/2 } else { x = openvg.VGfloat(w)*openvg.VGfloat(*px/100) - openvg.VGfloat(imw)/2 } if *py < 0 || *py > 100 { y = openvg.VGfloat(h)/2 - openvg.VGfloat(imh)/2 } else { y = openvg.VGfloat(h)*openvg.VGfloat(*py/100) - openvg.VGfloat(imh)/2 } openvg.Img(x, y, img) if len(*title) > 0 { var typ openvg.VGfloat fs := openvg.VGfloat(*fontsize/100.0) * openvg.VGfloat(w) if *texty == 0 { typ = y - fs*1.5 } else { typ = openvg.VGfloat(h) * openvg.VGfloat(*texty/100) } openvg.FillColor(*fgcolor) openvg.TextMid(x+openvg.VGfloat(imw)/2, typ, *title, "sans", int(fs)) } openvg.End() _ = <-sig_chan }
// 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) } }