// Trimmed ... func (t *Tree) Trimmed() *Tree { var leafs []image.Rectangle t.Visit(func(other *Tree) { if len(other.points) == 0 { return } leafs = append(leafs, image.Rectangle{ Min: other.Extents.Min, Max: other.Extents.Max, }) }) var r *image.Rectangle for _, b := range leafs { if r == nil { r = new(image.Rectangle) *r = b continue } *r = r.Union(b) } tr := New(*r, t.capacity) t.Visit(func(other *Tree) { for p := range other.points { tr.Insert(p) } }) return tr }
// // Private functions // func ContainerFit(outer, inner image.Rectangle) image.Rectangle { borderTop := image.Point{-18, -30} borderBottom := image.Point{18, 18} test := image.Rectangle{inner.Min.Add(borderTop), inner.Max.Add(borderBottom)} if outer.Size().X == 0 { return test } return outer.Union(test) }
func Invalidate(rect image.Rectangle) { for { select { case shouldPaint <- rect: return case r2 := <-shouldPaint: rect = rect.Union(r2) } } }
// NewBackground creates an xgraphics.Image which spans the entire screen, // initialized to black. func NewBackground(X *xgbutil.XUtil) (*xgraphics.Image, error) { res, err := randr.GetScreenResources(X.Conn(), X.RootWin()).Reply() if err != nil { return nil, err } var bgRect image.Rectangle for _, output := range res.Outputs { r, err := util.OutputRect(X, output) // NOTE: It doesn't really matter if this returns a Zero Rectangle. if err != nil { return nil, err } bgRect = bgRect.Union(r) } return xgraphics.New(X, bgRect), nil }
//Returns the rate of the union of r and rects. func rateOf(r image.Rectangle, union image.Rectangle, totalArea int) float64 { unionAndR := union.Union(r) wastedArea := area(unionAndR) - totalArea - area(r) return float64(wastedArea) * aspectRatio(unionAndR) }
func Paint(w wde.Window, rect image.Rectangle) { xOffset, yOffset := GetTopLeft() center := layout.Coord{ViewportWidth/2 - xOffset, ViewportHeight/2 - yOffset} if center != oldCenter || layout.Version() != oldVersion { oldCenter = center oldVersion = layout.Version() for x := 0; x <= ViewportWidth; x++ { for y := 0; y <= ViewportHeight; y++ { if layout.Visible(center, layout.Coord{x - xOffset, y - yOffset}) { res.Tile(terrain, res.Terrain, uint16(layout.GetSpace(x-xOffset, y-yOffset)), x, y) draw.Draw(terrain, image.Rect(x<<res.TileSize, y<<res.TileSize, (x+1)<<res.TileSize, (y+1)<<res.TileSize), image.Transparent, image.ZP, draw.Src) for _, t := range layout.Get(x-xOffset, y-yOffset) { if !t.NoClient() { res.Tile(terrain, res.Terrain, uint16(t), x, y) } } } else { res.Tile(terrain, image.Black, 0, x, y) } } } switch GetPlayerFlags() & packet.FlagSpriteMask { case packet.FlagEngineer: for x := 0; x <= ViewportWidth; x++ { for y := 0; y <= ViewportHeight; y++ { dx, dy := x-ViewportWidth/2, y-ViewportHeight/2 dist := dx*dx + dy*dy if dist <= 3*3 && layout.Visible(center, layout.Coord{x - xOffset, y - yOffset}) { for _, t := range layout.Get(x-xOffset, y-yOffset) { if t >= layout.WireW && t <= layout.WireS { res.Tile(terrain, res.Terrain, uint16(t), x, y) } } } } } } } minX, maxX := rect.Min.X>>res.TileSize, (rect.Max.X-1)>>res.TileSize+1 minY, maxY := rect.Min.Y>>res.TileSize, (rect.Max.Y-1)>>res.TileSize+1 draw.Draw(sprites, sprites.Bounds(), image.Transparent, image.ZP, draw.Src) var pixOffset image.Point var hasAnimation image.Rectangle paintLock.Lock() for _, p := range paintContexts { if layout.Visible(center, p.To) { x1, y1 := p.From.X+xOffset, p.From.Y+yOffset x2, y2 := p.To.X+xOffset, p.To.Y+yOffset if minX <= x2 && x2 <= maxX && minY <= y2 && y2 <= maxY { interp := float32(time.Since(p.Changed)*5) / float32(time.Second) if interp >= 1 { res.Tile(sprites, res.Actors, p.Sprite, x2, y2) } else { toInvalidate := image.Rect(x1, y1, x1+1, y1+1).Union(image.Rect(x2, y2, x2+1, y2+1)) if hasAnimation.Empty() { hasAnimation = toInvalidate } else { hasAnimation = hasAnimation.Union(toInvalidate) } if p == thePlayer.paint { pixOffset.X = int(float32((x1-x2)<<res.TileSize) * (1 - interp)) pixOffset.Y = int(float32((y1-y2)<<res.TileSize) * (1 - interp)) hasAnimation = viewport.Bounds() } res.TileFloat(sprites, res.Actors, p.Sprite, x1, y1, x2, y2, interp) } } } } paintLock.Unlock() draw.Draw(viewport, rect, terrain, rect.Min.Add(pixOffset), draw.Src) draw.Draw(viewport, rect, sprites, rect.Min.Add(pixOffset), draw.Over) draw.DrawMask(viewport, rect, image.Black, image.ZP, light.Image(-xOffset, -yOffset), rect.Min.Add(light.Origin(-xOffset, -yOffset)).Add(pixOffset), draw.Over) if image.Rect(0, 0, 1, 1).Overlaps(rect) { mouseTileLock.Lock() res.DrawString(viewport, mouseTileString, color.White, res.FontSmall, 1, 1) mouseTileLock.Unlock() } if !hasAnimation.Empty() { Invalidate(image.Rectangle{hasAnimation.Min.Mul(1 << res.TileSize), hasAnimation.Max.Mul(1 << res.TileSize)}) } paints++ /* // For debugging paints res.DrawString(viewport, strconv.FormatUint(paints, 10), color.White, res.FontSmall, 300, 1) draw.Draw(viewport, image.Rectangle{rect.Min, image.Pt(rect.Max.X+1, rect.Min.Y+1)}, image.White, image.ZP, draw.Src) draw.Draw(viewport, image.Rectangle{image.Pt(rect.Min.X-1, rect.Max.Y-1), rect.Max}, image.White, image.ZP, draw.Src) draw.Draw(viewport, image.Rectangle{rect.Min, image.Pt(rect.Min.X+1, rect.Max.Y+1)}, image.White, image.ZP, draw.Src) draw.Draw(viewport, image.Rectangle{image.Pt(rect.Max.X-1, rect.Min.Y-1), rect.Max}, image.White, image.ZP, draw.Src) //*/ w.Screen().CopyRGBA(viewport, viewport.Bounds()) w.FlushImage(rect) }
func main() { flag.Parse() b, err := loadFontFile() if err != nil { log.Fatal(err) } f, err := truetype.Parse(b) if err != nil { log.Fatal(err) } face := truetype.NewFace(f, &truetype.Options{ Size: *size, Hinting: parseHinting(*hinting), }) defer face.Close() fBounds := f.Bounds(fixed.Int26_6(*size * 64)) iBounds := image.Rect( +fBounds.Min.X.Floor(), -fBounds.Max.Y.Ceil(), +fBounds.Max.X.Ceil(), -fBounds.Min.Y.Floor(), ) tBounds := image.Rectangle{} glyphs := map[rune]*image.Gray{} advance := fixed.Int26_6(-1) ranges := loadRanges(f) for _, rr := range ranges { for r := rr[0]; r < rr[1]; r++ { dr, mask, maskp, adv, ok := face.Glyph(fixed.Point26_6{}, r) if !ok { log.Fatalf("could not load glyph for %U", r) } if advance < 0 { advance = adv } else if advance != adv { log.Fatalf("advance was not constant: got %v and %v", advance, adv) } dst := image.NewGray(iBounds) draw.DrawMask(dst, dr, image.White, image.Point{}, mask, maskp, draw.Src) glyphs[r] = dst tBounds = tBounds.Union(tightBounds(dst)) } } // height is the glyph image height, not the inter-line spacing. width, height := tBounds.Dx(), tBounds.Dy() buf := new(bytes.Buffer) fmt.Fprintf(buf, "// generated by go generate; DO NOT EDIT.\n\npackage %s\n\n", *pkg) fmt.Fprintf(buf, "import (\n\"image\"\n\n\"golang.org/x/image/font/basicfont\"\n)\n\n") fmt.Fprintf(buf, "// %s contains %d %d×%d glyphs in %d Pix bytes.\n", *vr, len(glyphs), width, height, len(glyphs)*width*height) fmt.Fprintf(buf, `var %s = basicfont.Face{ Advance: %d, Width: %d, Height: %d, Ascent: %d, Descent: %d, Left: %d, Mask: &image.Alpha{ Stride: %d, Rect: image.Rectangle{Max: image.Point{%d, %d*%d}}, Pix: []byte{ %s }, }, Ranges: []basicfont.Range{ %s }, }`, *vr, advance.Ceil(), width, face.Metrics().Height.Ceil(), -tBounds.Min.Y, +tBounds.Max.Y, tBounds.Min.X, width, width, len(glyphs), height, printPix(ranges, glyphs, tBounds), printRanges(ranges)) fmted, err := format.Source(buf.Bytes()) if err != nil { log.Fatalf("format.Source: %v", err) } if err := ioutil.WriteFile(*vr+".go", fmted, 0644); err != nil { log.Fatalf("ioutil.WriteFile: %v", err) } }