<?xml version="1.0" encoding="utf-8"?>
<developerConceptualDocument
	xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5"
	xmlns:xlink="http://www.w3.org/1999/xlink"
>

	<summary>
		<para>
		This page is &quot;developper's notes.&quot;
		</para>
		<para>
		These notes are written by developper for developper so basically worthy for only the developper
		but may worth for someone who is facing same problem as I've met.
		</para>
		<para>
		(In this note, a term CF is used to indicate .NET Compact Framework,
		and a term FF is used to indicate .NET Framework.)
		</para>
	</summary>

	<introduction>
		<autoOutline>1</autoOutline>
	</introduction>

	<section address="Optimization">
		<title>Optimization</title>
		<content>
			<para>These notes are about optimization.</para>
		</content>

		<sections>
		<!--******************************************************-->
		<section address="Buffer.BlockCopy">
			<title>Buffer.BlockCopy and Array.Copy</title>
			<content>
			<para>
			I found some people is saying that Buffer.BlockCopy is faster than Array.Copy.
			But as far as I tested, Buffer.BlockCopy is not significantly faster than Array.Copy
			so Azuki uses Array.Copy.
			</para>
			</content>
		</section>
		<!--******************************************************-->
		</sections>
	</section>

	<section address="cfissue">
		<title>about .NET Compact Framework</title>
		<content>
			<para></para>
		</content>
		<sections>
		<!--******************************************************-->
		<section address="resizing_array">
			<title>Resizing array</title>
			<content>
				<para>
				Array&lt;T&lt;.Resize does not exists on .NET Compact Framework
				so Azuki creates original resize logic for CF version.
				Note that if compared with Array&lt;T&gt;.Resize,
				my original logic is slightly slower
				so Azuki uses Array&lt;T&lt;.Resize for full version,
				and uses original logic for CF version.
				</para>
			</content>
		</section>
		<!--******************************************************-->
		</sections>
	</section>

	<section address="MeasureString">
		<title>Measuring string on .NET Compact Framework</title>
		<content>
			<para></para>
		</content>
		<sections>
		<!--******************************************************-->
		<section address="MeasureString_Problem">
			<title>Problem</title>
			<content>
				<para>
				System.Drawing.Graphics.DrawString / MeasureString automatically adds padding
				before drawing/measuring so I can not get exact drawing/calculation result from them.
				Although specifiying System.Drawing.StringFormat.GenericTypographic
				to them removes the padding, CF does not support GenericTypographic
				so I cannot use it.
				</para>
			</content>
		</section>
		<!--******************************************************-->
		<section address="MeasureString_TestCode">
			<title>TestCode</title>
			<content>
				<code lang="C#">
using( Graphics g = CreateGraphics() )
{
    string[] strs = new string[]{&quot;A&quot;, &quot;i&quot;, &quot;I&quot;, &quot;l&quot;, &quot;L&quot;, &quot;|&quot;, &quot;HOGE&quot;, &quot;.&quot;, &quot;あ&quot;};
    foreach( string str in strs )
    {
        Size s1 = Plat.Inst.MeasureText( g, str, Font ); // calling Win32API &quot;GetTextExtents&quot;
        Size s2 = g.MeasureString( str, Font ).ToSize();
        Size s3 = new Size();
        StringFormat sf = StringFormat.GenericTypographic;
        CharacterRange range = new CharacterRange( 0, str.Length );
        sf.SetMeasurableCharacterRanges( new CharacterRange[]{range} );
        Region[] regions = g.MeasureCharacterRanges( str, Font, new RectangleF(0,0,1000,1000), sf );
        if( 0 &lt; regions.Length )
            s3 = regions[0].GetBounds(g).Size.ToSize();
        
        Console.WriteLine( &quot;{0}, {1}\t{2}\t{3}&quot;, str, s1, s2, s3 );
    }
}
				</code>
			</content>
		</section>
		<!--******************************************************-->
		<section address="MeasureString_Result">
			<title>Result</title>
			<content>
				<para>
				The result when using &quot;MS Gothic (Japanese fixed width font)&quot; is next.
				</para>
				<code title=" ">
A, {Width=10, Height=19}        {Width=15.84722, Height=21}     {Width=9.333333, Height=18.66667}
 , {Width=10, Height=19}        {Width=6.222221, Height=21}     {Width=0, Height=0}
|, {Width=10, Height=19}        {Width=15.84722, Height=21}     {Width=9.333333, Height=18.66667}
HOGE, {Width=40, Height=19}     {Width=44.72222, Height=21}     {Width=37.33333, Height=18.66667}
., {Width=10, Height=19}        {Width=15.84722, Height=21}     {Width=9.333333, Height=18.66667}
あ, {Width=20, Height=19}       {Width=25.4388, Height=21}      {Width=18.66667, Height=18.66667}
				</code>
			</content>
		</section>
		<!--******************************************************-->
		<section address="MeasureString_Conclusion">
			<title>Conclusion</title>
			<content>
				<para>
				There is no portable way to determine exact metric of drawn text in C#.
				Therefore I must use platform drawing APIs through P/Invoke.
				</para>
			</content>
		</section>
		<!--******************************************************-->
		</sections>
	</section>

	<section address="DrawingSelection">
		<title>Drawing Selection</title>
		<content>
			<para>
			To represent &quot;selection&quot;, there are two ways.
			First one is simply drawing selected text with specified background color.
			Second one is inverting the selected text area.
			To use specific background color for selected text has no impact on performance
			and easy to implement.
			To invert text area, selection rectangle must be calculated by
			measuring selected text once so there may be slight effect on performance.
			I have not tested the difference
			but it's obvious that first choice will not cause trouble.
			Therefore Azuki took first one.
			</para>
		</content>
	</section>

	<section address="Invalidation">
		<title>Invalidation system in Windows.Forms GUI Toolkit</title>
		<content>
			<para>
			For unknown reason, calling Control.Invalidate with invalid rectangle DOES NOT affect to the
			ClipBounds property of Graphics object given at Control.Paint method
			without enabling double buffering by using Control.SetStyle.
			Control.SetStyle is not included in Compact Framework
			so Azuki avoids to use framework's invalidation system.
			</para>
		</content>
	</section>

	<section address="OverridingWindowProcedure">
		<title>Overwriting window procedure</title>
		<content>
			<para>
			Control.WndProc does not exist in Compact Framework so
			I overwrite window procedure by calling SetWindowLong API in CF build.
			On the other hand, in x64 Vista,
			overwriting window procedure of .NET Control windows by SetWindowLong
			with GWL_WNDPROC always fail for unknown reason as far as I tested.
			Therefore I override Control.WndProc in desktop build (not CF build).
			</para>
		</content>
	</section>

	<section address="LineHeightAndLineSpacing">
		<title>Line height and line spacing</title>
		<content>
			<para>
			Line height is calculated as height of '\x3000' [px].
			('\x3000' is full-width space char.)
			Line spacing is the distance between each lines.
			The underline for highlighting current line is drawn
			1px under the text so line spacing is larger than
			line height if highlighting is enabled.
			</para>
		</content>
	</section>


  <relatedTopics>
    <!-- One or more of the following:
         - A local link
         - An external link
         - A code entity reference

    <link xlink:href="Other Topic's ID"/>
    <link xlink:href="Other Topic's ID">Link inner text</link>

    <externalLink>
        <linkText>Link text</linkText>
        <linkAlternateText>Optional alternate link text</linkAlternateText>
        <linkUri>URI</linkUri>
    </externalLink>

    <codeEntityReference>API member ID</codeEntityReference>

    Examples:

    <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8270" />
    <link xlink:href="00e97994-e9e6-46e0-b420-5be86b2f8278">Some other topic</link>

    <externalLink>
        <linkText>SHFB on CodePlex</linkText>
        <linkAlternateText>Go to CodePlex</linkAlternateText>
        <linkUri>http://www.codeplex.com/SHFB</linkUri>
    </externalLink>

    <codeEntityReference>T:TestDoc.TestClass</codeEntityReference>
    <codeEntityReference>P:TestDoc.TestClass.SomeProperty</codeEntityReference>
    <codeEntityReference>M:TestDoc.TestClass.#ctor</codeEntityReference>
    <codeEntityReference>M:TestDoc.TestClass.#ctor(System.String,System.Int32)</codeEntityReference>
    <codeEntityReference>M:TestDoc.TestClass.ToString</codeEntityReference>
    <codeEntityReference>M:TestDoc.TestClass.FirstMethod</codeEntityReference>
    <codeEntityReference>M:TestDoc.TestClass.SecondMethod(System.Int32,System.String)</codeEntityReference>
    -->
  </relatedTopics>
</developerConceptualDocument>
