⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpartwork.java

📁 this is best wamp jkbkgnkldjkb jkfbjdksgkjl bjkgsbkjfdb gjdsblkj gbfkjsd
💻 JAVA
📖 第 1 页 / 共 4 页
字号:

			for (int j = dstRect.top; j < dstRect.bottom; j++) {
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, dstOffset++) {
					int opacityAlpha = opacityData[dstOffset] / 255;
					if (opacityAlpha > 0) {
						int destColor = undoData[dstOffset];
						if ((destColor & 0xff000000) != 0) {
							// opacityAlpha = 255 - opacityAlpha;

							int r = destColor >>> 16 & 0xff;
							int g = destColor >>> 8 & 0xff;
							int b = destColor & 0xff;

							r = r - (BURN_CONSTANT - r) * opacityAlpha / 255;
							g = g - (BURN_CONSTANT - g) * opacityAlpha / 255;
							b = b - (BURN_CONSTANT - b) * opacityAlpha / 255;

							if (r < 0) {
								r = 0;
							}
							if (g < 0) {
								g = 0;
							}
							if (b < 0) {
								b = 0;
							}

							int newColor = destColor & 0xff000000 | r << 16 | g << 8 | b;
							curLayer.data[dstOffset] = newColor;
						}
					}
				}
			}
		}
	}

	class CPBrushToolBlur extends CPBrushToolSimpleBrush {

		public void mergeOpacityBuf(CPRect dstRect, int color) {
			int[] opacityData = opacityBuffer.data;
			int[] undoData = undoBuffer.data;

			for (int j = dstRect.top; j < dstRect.bottom; j++) {
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, dstOffset++) {
					int opacityAlpha = opacityData[dstOffset] / 255;
					if (opacityAlpha > 0) {
						int blur = BLUR_MIN + (BLUR_MAX - BLUR_MIN) * opacityAlpha / 255;

						int destColor = undoData[dstOffset];
						int a = blur * (destColor >>> 24 & 0xff);
						int r = blur * (destColor >>> 16 & 0xff);
						int g = blur * (destColor >>> 8 & 0xff);
						int b = blur * (destColor & 0xff);
						int sum = blur + 4;

						destColor = undoData[j > 0 ? dstOffset - width : dstOffset];
						a += destColor >>> 24 & 0xff;
						r += destColor >>> 16 & 0xff;
						g += destColor >>> 8 & 0xff;
						b += destColor & 0xff;

						destColor = undoData[j < height - 1 ? dstOffset + width : dstOffset];
						a += destColor >>> 24 & 0xff;
						r += destColor >>> 16 & 0xff;
						g += destColor >>> 8 & 0xff;
						b += destColor & 0xff;

						destColor = undoData[i > 0 ? dstOffset - 1 : dstOffset];
						a += destColor >>> 24 & 0xff;
						r += destColor >>> 16 & 0xff;
						g += destColor >>> 8 & 0xff;
						b += destColor & 0xff;

						destColor = undoData[i < width - 1 ? dstOffset + 1 : dstOffset];
						a += destColor >>> 24 & 0xff;
						r += destColor >>> 16 & 0xff;
						g += destColor >>> 8 & 0xff;
						b += destColor & 0xff;

						a /= sum;
						r /= sum;
						g /= sum;
						b /= sum;
						curLayer.data[dstOffset] = a << 24 | r << 16 | g << 8 | b;
					}
				}
			}
		}
	}

	// Brushes derived from this class use the opacity buffer
	// as a simple alpha layer
	class CPBrushToolDirectBrush extends CPBrushToolSimpleBrush {

		public void mergeOpacityBuf(CPRect dstRect, int color) {
			int[] opacityData = opacityBuffer.data;
			int[] undoData = undoBuffer.data;

			for (int j = dstRect.top; j < dstRect.bottom; j++) {
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, dstOffset++) {
					int color1 = opacityData[dstOffset];
					int alpha1 = (color1 >>> 24);
					if (alpha1 <= 0) {
						continue;
					}
					int color2 = undoData[dstOffset];
					int alpha2 = (color2 >>> 24) * fusion.alpha / 100;

					int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
					if (newAlpha > 0) {
						int realAlpha = alpha1 * 255 / newAlpha;
						int invAlpha = 255 - realAlpha;

						curLayer.data[dstOffset] = newAlpha << 24
								| (((color1 >>> 16 & 0xff) * realAlpha + (color2 >>> 16 & 0xff) * invAlpha) / 255) << 16
								| (((color1 >>> 8 & 0xff) * realAlpha + (color2 >>> 8 & 0xff) * invAlpha) / 255) << 8
								| (((color1 & 0xff) * realAlpha + (color2 & 0xff) * invAlpha) / 255);
					}
				}
			}
		}
	}

	class CPBrushToolWatercolor extends CPBrushToolDirectBrush {

		static final int wcMemory = 50;
		static final int wxMaxSampleRadius = 64;

		LinkedList<CPColorFloat> previousSamples;

		public void beginStroke(float x, float y, float pressure) {
			previousSamples = null;

			super.beginStroke(x, y, pressure);
		}

		void paintDabImplementation(CPRect srcRect, CPRect dstRect, CPBrushDab dab) {
			if (previousSamples == null) {
				CPColorFloat startColor = sampleColor((dstRect.left + dstRect.right) / 2,
						(dstRect.top + dstRect.bottom) / 2, Math.max(1, Math.min(wxMaxSampleRadius,
								dstRect.getWidth() * 2 / 6)), Math.max(1, Math.min(wxMaxSampleRadius, dstRect
								.getHeight() * 2 / 6)));

				previousSamples = new LinkedList();
				for (int i = 0; i < wcMemory; i++) {
					previousSamples.addLast(startColor);
				}
			}
			CPColorFloat wcColor = new CPColorFloat(0, 0, 0);
			for (CPColorFloat sample : previousSamples) {
				wcColor.r += sample.r;
				wcColor.g += sample.g;
				wcColor.b += sample.b;
			}
			wcColor.r /= previousSamples.size();
			wcColor.g /= previousSamples.size();
			wcColor.b /= previousSamples.size();

			// resaturation
			int color = curColor & 0xffffff;
			wcColor.mixWith(new CPColorFloat(color), curBrush.resat * curBrush.resat);

			int newColor = wcColor.toInt();

			// bleed
			wcColor.mixWith(sampleColor((dstRect.left + dstRect.right) / 2, (dstRect.top + dstRect.bottom) / 2, Math
					.max(1, Math.min(wxMaxSampleRadius, dstRect.getWidth() * 2 / 6)), Math.max(1, Math.min(
					wxMaxSampleRadius, dstRect.getHeight() * 2 / 6))), curBrush.bleed);

			previousSamples.addLast(wcColor);
			previousSamples.removeFirst();

			paintDirect(srcRect, dstRect, dab.brush, dab.width, Math.max(1, dab.alpha / 4), newColor);
			mergeOpacityBuffer(0, false);
			if (sampleAllLayers) {
				fusionLayers();
			}
		}

		void paintDirect(CPRect srcRect, CPRect dstRect, byte[] brush, int w, int alpha, int color1) {
			int[] opacityData = opacityBuffer.data;

			int by = srcRect.top;
			for (int j = dstRect.top; j < dstRect.bottom; j++, by++) {
				int srcOffset = srcRect.left + by * w;
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, srcOffset++, dstOffset++) {
					int alpha1 = (brush[srcOffset] & 0xff) * alpha / 255;
					if (alpha1 <= 0) {
						continue;
					}

					int color2 = opacityData[dstOffset];
					int alpha2 = (color2 >>> 24);

					int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
					if (newAlpha > 0) {
						int realAlpha = alpha1 * 255 / newAlpha;
						int invAlpha = 255 - realAlpha;

						// The usual alpha blending formula C = A * alpha + B * (1 - alpha)
						// has to rewritten in the form C = A + (1 - alpha) * B - (1 - alpha) *A
						// that way the rounding up errors won't cause problems

						int newColor = newAlpha << 24
								| ((color1 >>> 16 & 0xff) + (((color2 >>> 16 & 0xff) * invAlpha - (color1 >>> 16 & 0xff)
										* invAlpha) / 255)) << 16
								| ((color1 >>> 8 & 0xff) + (((color2 >>> 8 & 0xff) * invAlpha - (color1 >>> 8 & 0xff)
										* invAlpha) / 255)) << 8
								| ((color1 & 0xff) + (((color2 & 0xff) * invAlpha - (color1 & 0xff) * invAlpha) / 255));

						opacityData[dstOffset] = newColor;
					}
				}
			}
		}

		CPColorFloat sampleColor(int x, int y, int dx, int dy) {
			LinkedList<CPColorFloat> samples = new LinkedList<CPColorFloat>();

			CPLayer layerToSample = sampleAllLayers ? fusion : getActiveLayer();

			samples.addLast(new CPColorFloat(layerToSample.getPixel(x, y) & 0xffffff));

			for (float r = 0.25f; r < 1.001f; r += .25f) {
				samples.addLast(new CPColorFloat(layerToSample.getPixel((int) (x + r * dx), y) & 0xffffff));
				samples.addLast(new CPColorFloat(layerToSample.getPixel((int) (x - r * dx), y) & 0xffffff));
				samples.addLast(new CPColorFloat(layerToSample.getPixel(x, (int) (y + r * dy)) & 0xffffff));
				samples.addLast(new CPColorFloat(layerToSample.getPixel(x, (int) (y - r * dy)) & 0xffffff));

				samples.addLast(new CPColorFloat(layerToSample.getPixel((int) (x + r * .7f * dx), (int) (y + r * .7f
						* dy)) & 0xffffff));
				samples.addLast(new CPColorFloat(layerToSample.getPixel((int) (x + r * .7f * dx), (int) (y - r * .7f
						* dy)) & 0xffffff));
				samples.addLast(new CPColorFloat(layerToSample.getPixel((int) (x - r * .7f * dx), (int) (y + r * .7f
						* dy)) & 0xffffff));
				samples.addLast(new CPColorFloat(layerToSample.getPixel((int) (x - r * .7f * dx), (int) (y - r * .7f
						* dy)) & 0xffffff));
			}

			CPColorFloat average = new CPColorFloat(0, 0, 0);
			for (CPColorFloat sample : samples) {
				average.r += sample.r;
				average.g += sample.g;
				average.b += sample.b;
			}
			average.r /= samples.size();
			average.g /= samples.size();
			average.b /= samples.size();

			return average;
		}
	}

	class CPBrushToolOil extends CPBrushToolDirectBrush {

		void paintDabImplementation(CPRect srcRect, CPRect dstRect, CPBrushDab dab) {
			if (brushBuffer == null) {
				brushBuffer = new int[dab.width * dab.height];
				for (int i = brushBuffer.length - 1; --i >= 0;) {
					brushBuffer[i] = 0;
				}
				// curLayer.copyRect(dstRect, brushBuffer);
				oilAccumBuffer(srcRect, dstRect, brushBuffer, dab.width, 255);
			} else {
				oilResatBuffer(srcRect, dstRect, brushBuffer, dab.width, (int) ((curBrush.resat <= 0f) ? 0 : Math.max(
						1, (curBrush.resat * curBrush.resat) * 255)), curColor & 0xffffff);
				oilPasteBuffer(srcRect, dstRect, brushBuffer, dab.brush, dab.width, dab.alpha);
				oilAccumBuffer(srcRect, dstRect, brushBuffer, dab.width, (int) ((curBrush.bleed) * 255));
			}
			mergeOpacityBuffer(0, false);
			if (sampleAllLayers) {
				fusionLayers();
			}
		}

		private void oilAccumBuffer(CPRect srcRect, CPRect dstRect, int[] buffer, int w, int alpha) {
			CPLayer layerToSample = sampleAllLayers ? fusion : getActiveLayer();

			int by = srcRect.top;
			for (int j = dstRect.top; j < dstRect.bottom; j++, by++) {
				int srcOffset = srcRect.left + by * w;
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, srcOffset++, dstOffset++) {
					int color1 = layerToSample.data[dstOffset];
					int alpha1 = (color1 >>> 24) * alpha / 255;
					if (alpha1 <= 0) {
						continue;
					}

					int color2 = buffer[srcOffset];
					int alpha2 = (color2 >>> 24);

					int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
					if (newAlpha > 0) {
						int realAlpha = alpha1 * 255 / newAlpha;
						int invAlpha = 255 - realAlpha;

						int newColor = newAlpha << 24
								| ((color1 >>> 16 & 0xff) + (((color2 >>> 16 & 0xff) * invAlpha - (color1 >>> 16 & 0xff)
										* invAlpha) / 255)) << 16
								| ((color1 >>> 8 & 0xff) + (((color2 >>> 8 & 0xff) * invAlpha - (color1 >>> 8 & 0xff)
										* invAlpha) / 255)) << 8
								| ((color1 & 0xff) + (((color2 & 0xff) * invAlpha - (color1 & 0xff) * invAlpha) / 255));

						buffer[srcOffset] = newColor;
					}
				}
			}
		}

		private void oilResatBuffer(CPRect srcRect, CPRect dstRect, int[] buffer, int w, int alpha1, int color1) {
			if (alpha1 <= 0) {
				return;
			}

			int by = srcRect.top;
			for (int j = dstRect.top; j < dstRect.bottom; j++, by++) {
				int srcOffset = srcRect.left + by * w;
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, srcOffset++, dstOffset++) {
					int color2 = buffer[srcOffset];
					int alpha2 = (color2 >>> 24);

					int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
					if (newAlpha > 0) {
						int realAlpha = alpha1 * 255 / newAlpha;
						int invAlpha = 255 - realAlpha;

						int newColor = newAlpha << 24
								| ((color1 >>> 16 & 0xff) + (((color2 >>> 16 & 0xff) * invAlpha - (color1 >>> 16 & 0xff)
										* invAlpha) / 255)) << 16
								| ((color1 >>> 8 & 0xff) + (((color2 >>> 8 & 0xff) * invAlpha - (color1 >>> 8 & 0xff)
										* invAlpha) / 255)) << 8
								| ((color1 & 0xff) + (((color2 & 0xff) * invAlpha - (color1 & 0xff) * invAlpha) / 255));

						buffer[srcOffset] = newColor;
					}
				}
			}
		}

		private void oilPasteBuffer(CPRect srcRect, CPRect dstRect, int[] buffer, byte[] brush, int w, int alpha) {
			int[] opacityData = opacityBuffer.data;

			int by = srcRect.top;
			for (int j = dstRect.top; j < dstRect.bottom; j++, by++) {
				int srcOffset = srcRect.left + by * w;
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, srcOffset++, dstOffset++) {
					int color1 = buffer[srcOffset];
					int alpha1 = (color1 >>> 24) * (brush[srcOffset] & 0xff) * alpha / (255 * 255);
					if (alpha1 <= 0) {
						continue;
					}

					int color2 = curLayer.data[dstOffset];
					int alpha2 = (color2 >>> 24);

					int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
					if (newAlpha > 0) {
						int realAlpha = alpha1 * 255 / newAlpha;
						int invAlpha = 255 - realAlpha;

						int newColor = newAlpha << 24
								| ((color1 >>> 16 & 0xff) + (((color2 >>> 16 & 0xff) * invAlpha - (color1 >>> 16 & 0xff)
										* invAlpha) / 255)) << 16
								| ((color1 >>> 8 & 0xff) + (((color2 >>> 8 & 0xff) * invAlpha - (color1 >>> 8 & 0xff)
										* invAlpha) / 255)) << 8
								| ((color1 & 0xff) + (((color2 & 0xff) * invAlpha - (color1 & 0xff) * invAlpha) / 255));

						opacityData[dstOffset] = newColor;

					}
				}
			}
		}
	}

	class CPBrushToolSmudge extends CPBrushToolDirectBrush {

		void paintDabImplementation(CPRect srcRect, CPRect dstRect, CPBrushDab dab) {
			if (brushBuffer == null) {
				brushBuffer = new int[dab.width * dab.height];
				smudgeAccumBuffer(srcRect, dstRect, brushBuffer, dab.width, 0);
			} else {
				smudgeAccumBuffer(srcRect, dstRect, brushBuffer, dab.width, dab.alpha);
				smudgePasteBuffer(srcRect, dstRect, brushBuffer, dab.brush, dab.width, dab.alpha);

				if (lockAlpha) {
					restoreAlpha(dstRect);
				}
			}
			opacityArea.makeEmpty();
			if (sampleAllLayers) {
				fusionLayers();
			}
		}

		public void mergeOpacityBuf(CPRect dstRect, int color) {
		}

		private void smudgeAccumBuffer(CPRect srcRect, CPRect dstRect, int[] buffer, int w, int alpha) {

			CPLayer layerToSample = sampleAllLayers ? fusion : getActiveLayer();

			int by = srcRect.top;
			for (int j = dstRect.top; j < dstRect.bottom; j++, by++) {
				int srcOffset = srcRect.left + by * w;
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, srcOffset++, dstOffset++) {
					int layerColor = layerToSample.data[dstOffset];
					int opacityAlpha = 255 - alpha;
					if (opacityAlpha > 0) {
						int destColor = buffer[srcOffset];

						int destAlpha = 255;
						int newLayerAlpha = opacityAlpha + destAlpha * (255 - opacityAlpha) / 255;
						int realAlpha = 255 * opacityAlpha / newLayerAlpha;
						int invAlpha = 255 - realAlpha;

						int newColor = (((layerColor >>> 24 & 0xff) * realAlpha + (destColor >>> 24 & 0xff) * invAlpha) / 255) << 24
								& 0xff000000
								| (((layerColor >>> 16 & 0xff) * realAlpha + (destColor >>> 16 & 0xff) * invAlpha) / 255) << 16
								& 0xff0000
								| (((layerColor >>> 8 & 0xff) * realAlpha + (destColor >>> 8 & 0xff) * invAlpha) / 255) << 8
								& 0xff00
								| (((layerColor & 0xff) * realAlpha + (destColor & 0xff) * invAlpha) / 255)
								& 0xff;

						if (newColor == destColor) {
							if ((layerColor & 0xff0000) > (destColor & 0xff0000)) {
								newColor += 1 << 16;
							} else if ((layerColor & 0xff0000) < (destColor & 0xff0000)) {
								newColor -= 1 << 16;
							}

							if ((layerColor & 0xff00) > (destColor & 0xff00)) {
								newColor += 1 << 8;
							} else if ((layerColor & 0xff00) < (destColor & 0xff00)) {
								newColor -= 1 << 8;
							}

							if ((layerColor & 0xff) > (destColor & 0xff)) {
								newColor += 1;
							} else if ((layerColor & 0xff) < (destColor & 0xff)) {
								newColor -= 1;
							}
						}

						buffer[srcOffset] = newColor;
					}
				}
			}

			if (srcRect.left > 0) {
				int fill = srcRect.left;
				for (int j = srcRect.top; j < srcRect.bottom; j++) {
					int offset = j * w;
					int fillColor = buffer[offset + srcRect.left];
					for (int i = 0; i < fill; i++) {
						buffer[offset++] = fillColor;
					}
				}
			}

			if (srcRect.right < w) {
				int fill = w - srcRect.right;
				for (int j = srcRect.top; j < srcRect.bottom; j++) {
					int offset = j * w + srcRect.right;
					int fillColor = buffer[offset - 1];
					for (int i = 0; i < fill; i++) {
						buffer[offset++] = fillColor;
					}
				}
			}

			for (int j = 0; j < srcRect.top; j++) {
				System.arraycopy(buffer, srcRect.top * w, buffer, j * w, w);
			}

			for (int j = srcRect.bottom; j < w; j++) {
				System.arraycopy(buffer, (srcRect.bottom - 1) * w, buffer, j * w, w);
			}
		}

		private void smudgePasteBuffer(CPRect srcRect, CPRect dstRect, int[] buffer, byte[] brush, int w, int alpha) {
			int[] undoData = undoBuffer.data;

			int by = srcRect.top;
			for (int j = dstRect.top; j < dstRect.bottom; j++, by++) {
				int srcOffset = srcRect.left + by * w;
				int dstOffset = dstRect.left + j * width;
				for (int i = dstRect.left; i < dstRect.right; i++, srcOffset++, dstOffset++) {
					int bufferColor = buffer[srcOffset];
					int opacityAlpha = (bufferColor >>> 24) * (brush[srcOffset] & 0xff) / 255;
					if (opacityAlpha > 0) {
						int destColor = undoData[dstOffset];

						int realAlpha = 255;
						int invAlpha = 255 - realAlpha;

						int newColor = (((bufferColor >>> 24 & 0xff) * realAlpha + (destColor >>> 24 & 0xff) * invAlpha) / 255) << 24
								& 0xff000000
								| (((bufferColor >>> 16 & 0xff) * realAlpha + (destColor >>> 16 & 0xff) * invAlpha) / 255) << 16
								& 0xff0000
								| (((bufferColor >>> 8 & 0xff) * realAlpha + (destColor >>> 8 & 0xff) * invAlpha) / 255) << 8
								& 0xff00
								| (((bufferColor & 0xff) * realAlpha + (destColor & 0xff) * invAlpha) / 255)
								& 0xff;

						curLayer.data[dstOffset] = newColor;
					}
				}
			}
		}
	}

	// ///////////////////////////////////////////////////////////////////////////////////
	// Layer methods
	// ///////////////////////////////////////////////////////////////////////////////////

	public void setActiveLayer(int i) {
		if (i < 0 || i >= layers.size()) {
			return;
		}

		activeLayer = i;
		curLayer = layers.get(i);
		callListenersLayerChange();
	}

	public int getActiveLayerNb() {
		return activeLayer;
	}

	public CPLayer getActiveLayer() {
		return curLayer;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -