<commit_before>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
package org.appcelerator.titanium.view;

import java.io.IOException;
import java.util.Arrays;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.FillType;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.Log;

public class TiBackgroundDrawable extends StateListDrawable {

	//private int backgroundColor;
	//private Bitmap backgroundImage;
	private static final String TAG = "TiBackgroundDrawable";

	private Drawable background;
	private Border border;
	private RectF outerRect, innerRect;
	private static final int NOT_SET = -1;
	private int alpha = NOT_SET;
	private Path path;
	private Paint paint;

	public TiBackgroundDrawable()
	{
		background = new ColorDrawable(Color.TRANSPARENT);
		border = null;
		outerRect = new RectF();
		innerRect = new RectF();
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
	}

	private void drawBorder(Canvas canvas)
	{
		paint.setColor(border.color);

		if (border.alpha > NOT_SET) {
			paint.setAlpha(border.alpha);
		}

		Bitmap borderBitmap = Bitmap
			.createBitmap((int) outerRect.width(), (int) outerRect.height(), Bitmap.Config.ARGB_8888);
		Canvas borderCanvas = new Canvas(borderBitmap);

		if (border.radius > 0) {
			borderCanvas.drawRoundRect(outerRect, border.radius, border.radius, paint);
		} else {
			borderCanvas.drawPaint(paint);
		}

		borderCanvas.save();

		if (border.radius > 0) {
			try {
				borderCanvas.clipPath(path);
			} catch (Exception e) {
				Log.w(TAG, "clipPath failed on canvas: " + e.getMessage());
			}
		} else {
			borderCanvas.clipRect(innerRect);
		}

		// To prevent the border from blending with the child view being framed, we need to create a transparent
		// region. This region will fill the inner rectangle with the child view being drawn on top.
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
		borderCanvas.drawRect(innerRect, paint);
		paint.setXfermode(null);

		borderCanvas.restore();

		canvas.drawBitmap(borderBitmap, 0, 0, paint);
	}

	@Override
	public void draw(Canvas canvas)
	{
		if (border != null) {
			drawBorder(canvas);
		}

		// paint.setColor(backgroundColor);
		if (background != null) {
			background.setBounds((int) innerRect.left, (int) innerRect.top, (int) innerRect.right, (int) innerRect.bottom);
		}

		canvas.save();

		if (border != null && border.radius > 0) {
			// This still happens sometimes when hw accelerated so, catch and warn
			try {
				canvas.clipPath(path);
			} catch (Exception e) {
				Log.w(TAG, "clipPath failed on canvas: " + e.getMessage());
			}
		} else {
			// innerRect == outerRect if there is no border
			//canvas.drawRect(innerRect, paint);
			canvas.clipRect(innerRect);
		}

		if (background != null) {
			if (alpha > NOT_SET) {
				background.setAlpha(alpha);
			}
			background.draw(canvas);
		}
		
		canvas.restore();

		/*if (backgroundImage != null && !backgroundImage.isRecycled()) {
			canvas.drawBitmap(backgroundImage, null, innerRect, paint);
		}*/
	}

	@Override
	protected void onBoundsChange(Rect bounds) {
		super.onBoundsChange(bounds);

		outerRect.set(bounds);
		int padding = 0;
		int maxPadding = 0;
		if (border != null) {
			//cap padding to current bounds
			maxPadding = (int) Math.min(outerRect.right/2, outerRect.bottom/2);
			padding = (int) Math.min((int)border.width, maxPadding);
		}
		innerRect.set(bounds.left+padding, bounds.top+padding, bounds.right-padding, bounds.bottom-padding);
		if (background != null) {
			background.setBounds((int)innerRect.left, (int)innerRect.top, (int)innerRect.right, (int)innerRect.bottom);
		}

		if (border != null && border.radius > 0) {
			path = new Path();
			float radii[] = new float[8];
			Arrays.fill(radii, border.radius);
			path.addRoundRect(innerRect, radii, Direction.CW);
			path.setFillType(FillType.EVEN_ODD);
		}
	}
<commit_msg>timob-8956: use canvas.drawPath() to draw boarder<commit_after>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
package org.appcelerator.titanium.view;

import java.io.IOException;
import java.util.Arrays;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.FillType;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.Log;

public class TiBackgroundDrawable extends StateListDrawable {

	//private int backgroundColor;
	//private Bitmap backgroundImage;
	private static final String TAG = "TiBackgroundDrawable";

	private Drawable background;
	private Border border;
	private RectF outerRect, innerRect;
	private static final int NOT_SET = -1;
	private int alpha = NOT_SET;
	private Path innerPath;
	private Path borderPath;
	private Paint paint;

	public TiBackgroundDrawable()
	{
		background = new ColorDrawable(Color.TRANSPARENT);
		border = null;
		outerRect = new RectF();
		innerRect = new RectF();
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
	}

	private void drawBorder(Canvas canvas)
	{
		paint.setColor(border.color);

		if (border.alpha > NOT_SET) {
			paint.setAlpha(border.alpha);
		}

		canvas.drawPath(borderPath, paint);
	}

	@Override
	public void draw(Canvas canvas)
	{
		if (border != null) {
			drawBorder(canvas);
		}

		if (background != null) {
			background.setBounds((int) innerRect.left, (int) innerRect.top, (int) innerRect.right, (int) innerRect.bottom);
		}

		canvas.save();

		if (border != null && border.radius > 0) {
			// This still happens sometimes when hw accelerated so, catch and warn
			try {
				canvas.clipPath(innerPath);
			} catch (Exception e) {
				Log.w(TAG, "clipPath failed on canvas: " + e.getMessage());
			}
		} else {
			canvas.clipRect(innerRect);
		}

		if (background != null) {
			if (alpha > NOT_SET) {
				background.setAlpha(alpha);
			}
			background.draw(canvas);
		}

		canvas.restore();
	}

	@Override
	protected void onBoundsChange(Rect bounds)
	{
		super.onBoundsChange(bounds);

		outerRect.set(bounds);

		int padding = 0;
		int maxPadding = 0;
		if (border != null) {
			// cap padding to current bounds
			maxPadding = (int) Math.min(outerRect.right / 2, outerRect.bottom / 2);
			padding = (int) Math.min((int) border.width, maxPadding);
		}
		innerRect.set(bounds.left + padding, bounds.top + padding, bounds.right - padding, bounds.bottom - padding);

		if (background != null) {
			background.setBounds((int) innerRect.left, (int) innerRect.top, (int) innerRect.right, (int) innerRect.bottom);
		}

		if (border != null) {
			if (border.radius > 0) {
				float radii[] = new float[8];
				Arrays.fill(radii, border.radius);
				borderPath = new Path();
				borderPath.addRoundRect(outerRect, radii, Direction.CW);
				borderPath.addRoundRect(innerRect, radii, Direction.CW);
				borderPath.setFillType(FillType.EVEN_ODD);
				innerPath = new Path();
				innerPath.addRoundRect(innerRect, radii, Direction.CW);
				innerPath.setFillType(FillType.EVEN_ODD);
			} else {
				borderPath = new Path();
				borderPath.addRect(outerRect, Direction.CW);
				borderPath.addRect(innerRect, Direction.CW);
				borderPath.setFillType(FillType.EVEN_ODD);
				innerPath = new Path();
				innerPath.addRect(innerRect, Direction.CW);
				innerPath.setFillType(FillType.EVEN_ODD);
			}
		}
	}

{'fraction_non_alphanumeric': 0.1168552036199095, 'fraction_numerical': 0.005429864253393665, 'mean_word_length': 4.303539292141572, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7154192', 'n_tokens_mistral': 3098, 'n_tokens_neox': 2760, 'n_words': 677}