byte[] buildBrushAA(byte[] brush, CPBrushInfo brushInfo) {
		int intSize = (int) (brushInfo.curSize + .99f);
		float center = intSize / 2.f;
		float sqrRadius = (brushInfo.curSize / 2) * (brushInfo.curSize / 2);
		float sqrRadiusInner = ((brushInfo.curSize - 2) / 2) * ((brushInfo.curSize - 2) / 2);
		float sqrRadiusOuter = ((brushInfo.curSize + 2) / 2) * ((brushInfo.curSize + 2) / 2);

		float xFactor = 1f + brushInfo.curSqueeze * MAX_SQUEEZE;
		float cosA = (float) Math.cos(brushInfo.curAngle);
		float sinA = (float) Math.sin(brushInfo.curAngle);

		int offset = 0;
		for (int j = 0; j < intSize; j++) {
			for (int i = 0; i < intSize; i++) {
				float x = (i + .5f - center);
				float y = (j + .5f - center);
				float dx = (x * cosA - y * sinA) * xFactor;
				float dy = (y * cosA + x * sinA);

				float sqrDist = dx * dx + dy * dy;

				if (sqrDist <= sqrRadiusInner) {
					brush[offset++] = (byte) 0xff;
				} else if (sqrDist > sqrRadiusOuter) {
					brush[offset++] = 0;
				} else {
					int count = 0;
					for (int oj = 0; oj < 4; oj++) {
						for (int oi = 0; oi < 4; oi++) {
							x = i + oi * (1.f / 4.f) - center;
							y = j + oj * (1.f / 4.f) - center;
							dx = (x * cosA - y * sinA) * xFactor;
							dy = (y * cosA + x * sinA);

							sqrDist = dx * dx + dy * dy;
							if (sqrDist <= sqrRadius) {
								count += 1;
							}
						}
					}
					brush[offset++] = (byte) Math.min(count * 16, 255);
				}
			}
		}

		return brush;
	}