/// <summary> /// Get the current or the first image and its rectangle /// </summary> private _ImageState GetImageState() { var states = _imageStates; if (states == null) { return(null); } int index = _currentState; if (index >= states.Length || states[index] == null) { index = 0; } _ImageState state = states[index]; int data = _baseData[index]; if ((data & State.MaskSizeDirty) != 0) { _baseData[index] = data & ~State.MaskSizeDirty; RefreshDrawRect(state, (data & State.MaskResizeImage) != 0); } return(state); }
/// <summary> /// Set a state object at the specific index /// </summary> protected void SetState(int index, State state) { int data = state.GetData(); var imageStates = _imageStates; var image = state.Image; if (image != null) { _baseData[index] = data | State.MaskSizeDirty; if (imageStates == null) { // create image states array imageStates = _imageStates = index == 0 ? new _ImageState[1] : new _ImageState[StateCount]; } else if (index >= imageStates.Length) { // enlarge image states array Array.Resize(ref imageStates, StateCount); _imageStates = imageStates; } else if (imageStates[index] != null) { // set image imageStates[index].image = image; goto END_SET_STATE; } // create image state object imageStates[index] = new _ImageState { image = image }; } else { _baseData[index] = data; if (imageStates != null && index < imageStates.Length && imageStates[index] != null) { imageStates[index].image = null; } } END_SET_STATE: // refresh the current state if (index == _currentState) { Invalidate(); } }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); _ImageState imgState = GetImageState(); if (imgState == null || imgState.image == null) { return; } SetColorMatrix(); var img = imgState.image; e.Graphics.DrawImage(img, imgState.area, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, _imgAttrs); }
/// <summary> /// Compute the rectangle of the image /// </summary> private void RefreshDrawRect(_ImageState state, bool resize) { Image image = state.image; if (image == null) { return; } var pad = Padding; int imgW = image.Width; int imgH = image.Height; int cW = Width - pad.Horizontal; int cH = Height - pad.Vertical; if (resize) { if (cW <= 0 || cH <= 0) { state.area = new Rectangle(); return; } double sw = (double)imgW / cW; double sh = (double)imgH / cH; if (sw < sh) { sw = sh; } imgW = (int)Math.Round(imgW / sw); imgH = (int)Math.Round(imgH / sw); } state.area = new Rectangle( pad.Left + (cW - imgW) / 2, pad.Top + (cH - imgH) / 2, imgW, imgH ); }