<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Red Stars &#187; Programming</title>
	<atom:link href="http://blog.red-stars.net/category/technology/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.red-stars.net</link>
	<description>Programming, food, and rambling</description>
	<lastBuildDate>Sat, 08 May 2010 16:19:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP string concatenation speed</title>
		<link>http://blog.red-stars.net/technology/programming/web/php-string-concatenation-speed/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/php-string-concatenation-speed/#comments</comments>
		<pubDate>Sat, 08 May 2010 16:18:39 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=224</guid>
		<description><![CDATA[Something I have always wondered is the speed difference between concatenation strings with in-string variables verses the . operator. I've always assumed . would be much faster, and today I found out. $amount = 0x1FFFF; $start = microtime(true); while ($amount--) $throwAway = "this is a test at the $amount point!"; //$throwAway = "this is a [...]]]></description>
			<content:encoded><![CDATA[<p>Something I have always wondered is the speed difference between concatenation strings with in-string variables verses the . operator. I've always assumed . would be much faster, and today I found out.</p>
<pre class="brush:php">$amount = 0x1FFFF;
$start = microtime(true);

while ($amount--)
	$throwAway = "this is a test at the $amount point!"; //$throwAway = "this is a test at the ". $amount ." point!";

	echo "Time: ". (microtime(true) - $start);</pre>
<p>Exactly as expected, leaving it up to in-string parsing of variables ended up with a bench mark time of 0.1574 and manually concatenating in the variable was 0.1384, which is not a huge difference, but I wanted to see how this would scale when doing multiple concatenations. The string was changed to $throwAway = "this is ". $amount ." a test ". $amount ." at the ". $amount ." point!"; and it's respective in-string.</p>
<p>What I found is that it actually scales to <em>in-string</em> far better! In-string averaged to 0.3235 and manual to 0.3597. After some research it turns out this is because it does a single large concatenation while manually doing it could perform the operation 3 separate times.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/php-string-concatenation-speed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Array Performance</title>
		<link>http://blog.red-stars.net/uncategorized/php-array-performance/</link>
		<comments>http://blog.red-stars.net/uncategorized/php-array-performance/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 13:42:02 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=204</guid>
		<description><![CDATA[Index Checking The functional difference between array_key_exists($key, $array) and isset($array[$key]) is that isset returns false when the key exists but contains null. Functionality aside, there is a demonstrable performance difference. $dataSet = array(); $size = 0x1FFFF; $i = $size; while ($i--) $dataSet[$i] = $i+1; $start = microtime(true); $i = $size; while ($i--) array_key_exists($i, $dataSet); //isset($dataSet[$i]); [...]]]></description>
			<content:encoded><![CDATA[<span id="Index_Checking"><h3>Index Checking</h3></span>
<p>The functional difference between array_key_exists($key, $array) and isset($array[$key]) is that isset returns false when the key exists but contains null. Functionality aside, there is a demonstrable performance difference.</p>
<pre class="brush:php">$dataSet = array();
$size = 0x1FFFF;

$i = $size;
while ($i--)
	$dataSet[$i] = $i+1;

$start = microtime(true);

$i = $size;
while ($i--)
	array_key_exists($i, $dataSet); //isset($dataSet[$i]);

echo "Time: ". (microtime(true) - $start);</pre>
<p>Sure enough, after averaging a few benchmarks together the outcome was clear.</p>
<dl>
<dt>isset</dt>
<dd>0.0248870849609</dd>
<dt>array_key_exists</dt>
<dd>0.604112148285</dd>
</dl>
<p>When performance is important target isset() when applicable. It's even possible to use a fall through to increase performance, here's an example from my Options class: if (!isset($this->_options[$resolvedName]) &#038;& !array_key_exists($resolvedName, $this->_options))</p>
<span id="Append_Performance"><h3>Append Performance</h3></span>
<p>In the following test case there was no performance difference between usage of append or directly addressing an index.</p>
<pre class="brush:php">$dataSet = array();
$size = 0x1FFFF;
$i = $size;

$start = microtime(true);

while ($i--)
	$dataSet[] = $i+1; //$dataSet[$i] = $i+1;

echo "Time: ". (microtime(true) - $start);</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/uncategorized/php-array-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remodeling PHP&#8217;s compact()/extract() into an OO Pattern</title>
		<link>http://blog.red-stars.net/technology/programming/web/remodeling-phps-compactextract-into-an-oo-pattern/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/remodeling-phps-compactextract-into-an-oo-pattern/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 16:38:47 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=185</guid>
		<description><![CDATA[A common usage, at least for extract(), has been to allow an associative array to be passed to a function for use as named optional parameters, however, there is a lot wrong with dumping an array into the symbol table and then checking if what you want exists or not. I have designed a pattern [...]]]></description>
			<content:encoded><![CDATA[<p>A common usage, at least for extract(), has been to allow an associative array to be passed to a function for use as named optional parameters, however, there is <em>a lot</em> wrong with dumping an array into the symbol table and then checking if what you want exists or not.</p>
<p>I have designed a pattern that allows an object to accept and address public level optional named arguments without the problems that could be associated with the compact()/extract() pattern. This pattern does require at least PHP 5.3 (uses late static binding) and overloads __get/__set preventing the child class from doing so.</p>
<p><span id="more-185"></span></p>
<span id="Usage"><h2>Usage</h2></span>
<p>Possible optional keys are defined as class constants, if one is addressed or set that is undefined an exception will be thrown. Instead of using extract(), the inherited SetOptionalProperties($array) method should be called to set the values. The value's can be addressed by it's constants name like it's a property, like $instance->ConstantName. Default values can be given by overloading the protected static $_defaultOptions member. The example shows this in with more detail:</p>
<span id="Example"><h3>Example</h3></span>
<pre class="brush:php">class MyClass extends Options {
	public $Property;

	const MyOption = "MyOption";
	const AnotherOption = "AnotherOption";

	protected static $_defaultOptions = array(self::AnotherOption = "default value!");

	public function __construct($property, $options = array()) {
		$this->Property = $property;
		$this->SetOptionalProperties($options); // this allows Options to access the optional values.
	}
}

$instance = new MyClass("property's value", array(MyClass::MyOption = "my option value!"));
echo "MyOption: '{$instance->MyOption}', AnotherOption: '{$instance->AnotherOption}', Property: '{$instance->Property}'";</pre>
<span id="Output:"><h4>Output:</h4></span>
<pre>MyOption: 'my option value!', AnotherOption: 'default value!', Property: 'property's value'</pre>
<span id="Class"><h3>Class</h3></span>
<pre class="brush:php">abstract class Options {
	/// The array which stores the optional values
	private $_options = array();

	/// This array should be overloaded by child classes if default values are going to be used.
	protected static $_defaultOptions = array();

	/// Use Options::$AllowUndefinedProperties = true; to prevent exceptions from being thrown when an undefined
	/// property is set or fetched.
	public static $AllowUndefinedProperties = false;

	public function &#038;__get($name) {
		$resolvedName = $this->ResolveOptionName($name);

		// Do we have a value? Use the isset/array_key_exists fall through to speed up access to existing non-null entries.
		if (!isset($this->_options[$resolvedName]) &#038;& !array_key_exists($resolvedName, $this->_options)) {
			// Do we have a default value?
			if (array_key_exists($resolvedName, static::$_defaultOptions))
				$this->_options[$resolvedName] = static::$_defaultOptions[$resolvedName];
			else
				$this->_options[$resolvedName] = null;
		}

		return $this->_options[$resolvedName];
	}

	public function __set($name, $value) {
		$resolvedName = $this->ResolveOptionName($name);

		return $this->_options[$resolvedName] = $value;
	}

	public function __isset($name) {
		$resolvedName = $this->ResolveOptionName($name);

		return isset($this->_options[$resolvedName]);
	}

	public function __unset($name) {
		$resolvedName = $this->ResolveOptionName($name);

		unset($this->_options[$resolvedName]);
	}

	/**
	 * Set the optional properties for the class.
	 * @param $options A [ClassConstant] = Value indexed array of optional properties.
	 */
	protected function SetOptionalProperties(array $options) {
		$this->_options = $options;
	}

	/// Resolve any aliases name to the proper name.
	private function ResolveOptionName($name) {
		$constant = "static::". $name;

		if (defined($constant))
			return constant($constant);
		else if (!self::$AllowUndefinedProperties)
			throw new Exception("Undefined property or option '$name' being set in ". get_called_class());

	}
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/remodeling-phps-compactextract-into-an-oo-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Queryable Food Nutrition Database</title>
		<link>http://blog.red-stars.net/technology/programming/web/queryable-food-nutrition-database/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/queryable-food-nutrition-database/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:42:06 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=175</guid>
		<description><![CDATA[The USDA releases data for food nutritional information. I've taken this data and loaded it into my local database, and created a front end to allow it to be queryable. Database Schema Sample Queries Top 150 protein containing foods SELECT Foods.Description, concat( NutrientValue, Units ) AS Value FROM Foods JOIN NutrientDefinitions ON ( NutrientName = [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ars.usda.gov/Services/docs.htm?docid=17478">The USDA</a> releases data for food nutritional information. I've taken this data and loaded it into my local database, and created <a href="http://fooddb.red-stars.net">a front end to allow it to be queryable.</a></p>
<span id="Database_Schema"><h2>Database Schema</h2></span>
<p><img src="http://red-stars.net/pictures/fooddb.png" alt="database schema" /></p>
<p><span id="more-175"></span></p>
<span id="Sample_Queries"><h2>Sample Queries</h2></span>
<span id="Top_150_protein_containing_foods"><h3>Top 150 protein containing foods</h3></span>
<p><code>SELECT Foods.Description, concat( NutrientValue, Units ) AS Value<br />
FROM Foods<br />
JOIN NutrientDefinitions ON ( NutrientName = 'Protein' )<br />
JOIN NutrientData<br />
USING ( NutrientID, FoodID )<br />
ORDER BY NutrientValue DESC<br />
LIMIT 150</code></p>
<span id="Top_100_protein_containing_legumes"><h3>Top 100 protein containing legumes</h3></span>
<p><code>SELECT Foods.Description, concat( NutrientValue, Units ) AS Value<br />
FROM FoodGroups<br />
JOIN Foods<br />
USING ( CategoryID )<br />
JOIN NutrientDefinitions ON ( NutrientName = 'Protein' )<br />
JOIN NutrientData<br />
USING ( NutrientID, FoodID )<br />
WHERE FoodGroups.Description like '%LEGUME%'<br />
ORDER BY NutrientValue DESC<br />
LIMIT 100</code></p>
<span id="Top_150_iron_containing_foods"><h3>Top 150 iron containing foods</h3></span>
<p><code>SELECT Foods.Description, concat( NutrientValue, Units ) AS Value<br />
FROM Foods<br />
JOIN NutrientDefinitions ON ( NutrientName like '%Iron%' )<br />
JOIN NutrientData<br />
USING ( NutrientID, FoodID )<br />
ORDER BY NutrientValue DESC<br />
LIMIT 150</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/queryable-food-nutrition-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Message Hasher</title>
		<link>http://blog.red-stars.net/technology/software/message-hasher/</link>
		<comments>http://blog.red-stars.net/technology/software/message-hasher/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 01:09:09 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=168</guid>
		<description><![CDATA[A small web-based message hasher, good for generating hashes of small amounts of text. No binary support yet, but it's planned via file uploads! #hasherform { display: inline-block; width: 400px; } #hasherform .wide { width: 100%; } #hasherform form * { margin-top: 8px; } #hasherform textarea { height: 10em; } Short Message Hasher Algorithm md2 [...]]]></description>
			<content:encoded><![CDATA[<p>A small web-based message hasher, good for generating hashes of small amounts of text. No binary support yet, but it's planned via file uploads!</p>
<p><span id="more-168"></span><br />
<style type="text/css">
	#hasherform {
		display: inline-block;
		width: 400px;
	}
	#hasherform .wide {
		width: 100%;
	}
	#hasherform form * {
		margin-top: 8px;
	}
	#hasherform textarea {
		height: 10em;
	}
</style>
<fieldset id="hasherform">
<legend>Short Message Hasher</legend>
<form method="get" target="/index.php">
		<label for="algorithm">Algorithm</label></p>
<select name="algorithm" class="wide" id="algorithm">
<option value="md2">md2</option>
<option value="md4">md4</option>
<option value="md5">md5</option>
<option value="sha1">sha1</option>
<option value="sha256">sha256</option>
<option value="sha384">sha384</option>
<option value="sha512">sha512</option>
<option value="ripemd128">ripemd128</option>
<option value="ripemd160">ripemd160</option>
<option value="ripemd256">ripemd256</option>
<option value="ripemd320">ripemd320</option>
<option value="whirlpool">whirlpool</option>
<option value="tiger128,3">tiger128,3</option>
<option value="tiger160,3">tiger160,3</option>
<option value="tiger192,3">tiger192,3</option>
<option value="tiger128,4">tiger128,4</option>
<option value="tiger160,4">tiger160,4</option>
<option value="tiger192,4">tiger192,4</option>
<option value="snefru">snefru</option>
<option value="gost">gost</option>
<option value="adler32">adler32</option>
<option value="crc32">crc32</option>
<option value="crc32b">crc32b</option>
<option value="haval128,3">haval128,3</option>
<option value="haval160,3">haval160,3</option>
<option value="haval192,3">haval192,3</option>
<option value="haval224,3">haval224,3</option>
<option value="haval256,3">haval256,3</option>
<option value="haval128,4">haval128,4</option>
<option value="haval160,4">haval160,4</option>
<option value="haval192,4">haval192,4</option>
<option value="haval224,4">haval224,4</option>
<option value="haval256,4">haval256,4</option>
<option value="haval128,5">haval128,5</option>
<option value="haval160,5">haval160,5</option>
<option value="haval192,5">haval192,5</option>
<option value="haval224,5">haval224,5</option>
<option value="haval256,5">haval256,5</option>
</select>
<p>
		<label for="message">Message</label><br />
		<textarea name="data" class="wide" id="message"></textarea></p>
<input type="checkbox" name="raw" id="rawcheckbox" /><label for="rawcheckbox">Return as raw data</label></p>
<input type="submit" value="Hash!" />
	</form>
</fieldset>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/software/message-hasher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Google Page Rank Finder in Javascript</title>
		<link>http://blog.red-stars.net/technology/programming/web/creating-a-google-page-rank-finder-in-javascript/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/creating-a-google-page-rank-finder-in-javascript/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 14:06:28 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=63</guid>
		<description><![CDATA[The google.search.WebSearch API quickly explained, also quickly complained about. It's fast, powerful, and well done, but Google gypped us on functionality.]]></description>
			<content:encoded><![CDATA[<p>An interesting technology are Google Page Rank Finders. What they do is discover which result and page number a website is in Google's search results for a given term.</p>
<p>I thought an interesting implementation would be a completely client side one written in Javascript using Google's search API. To spoil the ending, after creating this I discovered the API only allows 8 results per page and 8 pages, making this useless if the site is beyond the 64th result, but the API is interesting and powerful regardless.</p>
<p>The finished version can be found at <a href="http://pagerank.red-stars.net/">pagerank.red-stars.net</a> with the complete <a href="http://pagerank.red-stars.net/pagerank.js">Javascript</a>.</p>
<p><span id="more-63"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#google.search.WebSearch_object">google.search.WebSearch() object</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<span id="google.search.WebSearch_object"><h3>google.search.WebSearch() object</h3></span>
<p>The WebSearch() object is relatively simple, once instanced, all it needs is a call back to be setup before it can be used.</p>
<pre class="brush:javascript">var webSearch = new google.search.WebSearch();
webSearch.setSearchCompleteCallback(this, searchComplete, null);
webSearch.execute("cookies");</pre>
<p>The function searchComplete() will be called when the search for "cookies" completes. It's important that our instance of WebSearch named webSearch is inside of a scope which is viewable from searchComplete() because the callback is argumentless.
<pre class="brush:javascript">function searchComplete() {
	// Make sure that there are results.
	if (webSearch.results &#038;& webSearch.results.length > 0) {
		var results = webSearch.results;
		// Go through every result.
		for (var resultIndex = 0; resultIndex < results.length; resultIndex++) {
			var result = results[resultIndex];
			// Show a messagebox with the results information.
			alert(result.html.innerHTML);
		}
	}
}</pre>
<p>We used the .html property from the result which gives us a Google-looking result. Now what if we wanted more than just the first page?</p>
<pre class="brush:javascript">var currentPageIndex = 0;
function searchComplete() {
	// Make sure that there are results.
	if (webSearch.results &#038;& webSearch.results.length > 0) {
		currentPageIndex++;
		var results = webSearch.results;
		// Go through every result.
		for (var resultIndex = 0; resultIndex < results.length; resultIndex++) {
			var result = results[resultIndex];
			// Show a messagebox with the results information.
			alert(result.html.innerHTML);
		}

		// Check if another page exists, if so, perform the request.
		if (currentPageIndex < webSearch.cursor.pages.length)
			webSearch.gotoPage(currentPageIndex);
	}
}</pre>
<p>The <code>cursor</code> object contains an array called pages who's length is used to determine the number of pages available. This will go through all available search results. When <code>gotoPage</code> is called, our call back function is once again executed when the search is finished.</p>
<p>A complete reference to the WebSearch and associate classes <a href="http://code.google.com/apis/ajaxsearch/documentation/reference.html">is available on code.google.com</a>. The API is decent and flexible, if not limited in functionality.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/creating-a-google-page-rank-finder-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>System.Drawing.Drawing2D.PathPointType defined.</title>
		<link>http://blog.red-stars.net/technology/programming/csharp/system-drawing-drawing2d-pathpointtype-defined/</link>
		<comments>http://blog.red-stars.net/technology/programming/csharp/system-drawing-drawing2d-pathpointtype-defined/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 19:07:57 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=50</guid>
		<description><![CDATA[Microsoft's under-documented class getting it's rightful treatment.]]></description>
			<content:encoded><![CDATA[<p>I had a project which involved raw access to the data stored inside of a System.Drawing.Drawing2D.GraphicsPath and found that the <a title="MSDN Document" href="http://msdn.microsoft.com/en-us/library/3ch9cxht.aspxhttp://">MSDN Document</a> for PathPointType was rather lacking, but it's not too complex.</p>
<p><span id="more-50"></span></p>
<p>Inside of GraphicsPath is a byte array called PathTypes that contains PathPointType and a PointF array called PathPoints (the same data is also stored in GraphicsPath.PathData.Points and GraphicsPath.PathData.Types). They relate to each other by index, so PathTypes[n] is the PathPointTypes for PathPoints[n].</p>
<p>The reason PathTypes is stored as bytes and not PathPointType is because multiple values will be contained per byte. To separate the two, you must use a bitwise AND operation of your value against the bit mask PathPointType.PathTypeMask. The resulting value is either Start, Line or Bezier (Bezier3 is equal to Bezier).</p>
<p>You can NOT modify these collections directly. Instead, you must make a new instance of GraphicsPaths and pass modified collections to them via the (PointF[], byte[]) constructor.</p>
<table style="width: 100%; border: 1px solid black;">
<caption>PathPointType values</caption>
<thead>
<tr>
<td><strong>PathPointType</strong></td>
<td><strong>Value</strong>
<td><strong>Description</strong></td>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>Start</td>
<td style="text-align: right;">0</td>
<td>Start of graphics path. Move cursor then put pen down.</td>
</tr>
<tr>
<td>Line</td>
<td style="text-align: right;">1</td>
<td>Move pen to given location.</td>
</tr>
<tr>
<td>Bezier</td>
<td style="text-align: right;">3</td>
<td>Draw curve.</td>
</tr>
<tr>
<td>Bezier3</td>
<td style="text-align: right;">3</td>
<td><em>Equal to Bezier.</em></td>
</tr>
<tr>
<td>PathTypeMask</td>
<td style="text-align: right;">7</td>
<td>Mask for extracting types from PathTypes.</td>
</tr>
<tr>
<td>DashMode</td>
<td style="text-align: right;">16</td>
<td>Draw in dashes, not solid lines.</td>
</tr>
<tr>
<td>PathMarker</td>
<td style="text-align: right;">32</td>
<td>Lift pen, move pen to new location, then if the pen was down before, place back down.</td>
</tr>
<tr>
<td>CloseSubpath</td>
<td style="text-align: right;">128</td>
<td>Move mouse to point from the last Start (closing the path) then lift pen.</td>
</tr>
</tbody>
</table>
<p>Below is code which parses the PathTypes and PathPoints and causes actions in a class which renders the GraphicsPath as mouse output where the mouse is down when the pen should be down, and the mouse moves to the location the pen should be, etc. Please note this code renders Bezier curves as lines.</p>
<pre class="brush:csharp">int index=0;
PointF firstPoint = new PointF(); // Used to store the starting position so closed paths can reposition here.
// Loop through all path data
foreach (PointF point in Path.PathPoints) {
	byte curType = Path.PathTypes[index];
				// Extract the item type by the bit mask
	byte itemType = (byte)(curType &#038; (byte)PathPointType.PathTypeMask);

	// Draw the different object types
	if (itemType == (byte)PathPointType.Start) {
		firstPoint = point;
		input.MousePos(point);
		input.LeftButtonDown();
	} else if ((itemType == (byte)PathPointType.Line) || (itemType == (byte)PathPointType.Bezier) || (itemType == (byte)PathPointType.Bezier3))
		input.MousePos(point);

	// Handle all additional flags
	if (isType(curType, PathPointType.PathMarker)) {
		bool wasMouseDown = false;
		if (input.IsMouseDown) {
			wasMouseDown = true;
			input.LeftButtonUp();
		}
		input.MousePos(point);
		if (wasMouseDown)
			input.LeftButtonDown();
	}

	if (isType(curType, PathPointType.CloseSubpath)) {
		input.MousePos(firstPoint);
		input.LeftButtonUp();
	}
	index++;
}
input.LeftButtonUp();</pre>
<pre class="brush:csharp">private bool isType(byte type, PathPointType isType) {
	return (type &amp; (byte)isType) != 0;
 }</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/csharp/system-drawing-drawing2d-pathpointtype-defined/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
