github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/emask/helper_buffer.go (about)

     1  package emask
     2  
     3  // A common buffer implementation shared by edge_marker and outliner.
     4  type buffer struct {
     5  	Width  int // canvas width, in pixels
     6  	Height int // canvas height, in pixels
     7  	Values []float64
     8  	// ^ Negative values are used for counter-clockwise segments,
     9  	//   positive values are used for clockwise segments.
    10  }
    11  
    12  // Sets a new Width and Height and resizes the underlying buffer
    13  // if necessary. The buffer contents are always cleared too.
    14  func (self *buffer) Resize(width, height int) {
    15  	if width <= 0 || height <= 0 {
    16  		panic("width or height <= 0")
    17  	}
    18  	self.Width = width
    19  	self.Height = height
    20  	totalLen := width * height
    21  	if len(self.Values) == totalLen {
    22  		// nothing
    23  	} else if len(self.Values) > totalLen {
    24  		self.Values = self.Values[0:totalLen]
    25  	} else { // len(self.Values) < totalLen
    26  		if cap(self.Values) >= totalLen {
    27  			self.Values = self.Values[0:totalLen]
    28  		} else {
    29  			self.Values = make([]float64, totalLen)
    30  			return // stop before ClearBuffer()
    31  		}
    32  	}
    33  
    34  	self.Clear()
    35  }
    36  
    37  // Fills the internal buffer with zeros.
    38  func (self *buffer) Clear() { fastFillFloat64(self.Values, 0) }
    39  
    40  // Performs the boundary change accumulation operation storing
    41  // the results into the given buffer. Used with the edge marker
    42  // rasterizer.
    43  func (self *buffer) AccumulateUint8(buffer []uint8) {
    44  	if len(buffer) != self.Width*self.Height {
    45  		panic("uint8 buffer has wrong length")
    46  	}
    47  
    48  	index := 0
    49  	for y := 0; y < self.Height; y++ {
    50  		accumulator := float64(0)
    51  		accUint8 := uint8(0)
    52  		for x := 0; x < self.Width; x++ {
    53  			value := self.Values[index]
    54  			if value != 0 { // small optimization
    55  				accumulator += value
    56  				accUint8 = uint8(clampUnit64(abs64(accumulator)) * 255)
    57  			}
    58  			buffer[index] = accUint8
    59  			index += 1
    60  		}
    61  	}
    62  }